2015-04-23 52 views
2

我正在创建一个需要创建特定资源的项目,同时创建资源时我还在文件中写入以在发生错误时回滚该创建过程。 但在这里捕捞,资源在刚刚创建它们相反的方式被删除,所以,当我在卷回写文件是这样的:如何以自底向上的方式使用批处理方式读取文本文件

delete R1 
delete R2 
.. 
.. 
delete RN 

我要删除的资源为了 - >

delete RN 
delete RN-1 
.... 
... 
delete R1 

有没有办法做到这一点在Windows批处理?

回答

2

没有使用批处理按相反顺序读取文件的本机方式。

但是,虽然不是最快的方法,但它可以按正常顺序读取文件,以填充数字为每行加前缀,按相反顺序对列表进行排序,拆分行以分隔数字,然后处理列表

@echo off 
    setlocal enableextensions disabledelayedexpansion 

    set "file=data.txt" 

    for /f "tokens=1,* delims=¬" %%a in (' 
     cmd /v:off /e /q /c"set "counter^=10000000" & for /f usebackq^ delims^=^ eol^= %%c in ("%file%") do (set /a "counter+^=1" & echo(¬%%c)" 
     ^| sort /r 
    ') do (
     echo %%b 
    ) 

工作原理:

该代码将用于在输入文件中的每一行,输出一个数字前缀和线,用定界符(¬)以后能够两个元件分开。

随着后面的数据将被排序,我们需要前缀具有统一的长度。因此,我们初始化计数器10000000,增加它因此在所有行前缀具有相同的长度(注意:如果您的文件已经超过99999999行,,不要使用此方法)

要改变我们将简单地使用set /a "counter+=1",但为了在循环内回显它,我们需要延迟扩展,但这可能会导致文件中的数据产生问题(我不知道它是否可以包含!字符)。

我们可以启用/禁用延迟扩展来处理它,但是因为这对于每一行都是必需的,所以会出现性能损失。为了解决这个问题,代码在一个单独的cmd实例中执行。

为什么一个单独的实例?这个单独实例中的代码不是在批处理上下文中执行的,而是在命令行上下文中执行的。在命令行上下文中,set /a命令与calc的结果相呼应,所以我们不需要这样做,延迟的扩展问题就消失了。我们只需计算新的计数器(得到回显),然后回显分隔符和输入文件中的行。因此,我们有以下的代码

set "counter=10000000" 
for /f usebackq^ delims^=^ eol^= %%c in ("%file%") do (
    set /a "counter+=1" 
    echo(¬%%c 
) 

它写成一个串联的命令,并作为参数传递给cmd实例传入(注:^被用来逃避问题的字符),即用echo off/q),扩展执行启用(/e)和禁用延迟膨胀(/v:off

cmd /v:off /e /q /c"set "counter^=10000000" & for /f usebackq^ delims^=^ eol^= %%c in ("%file%") do (set /a "counter+^=1" & echo(¬%%c)" 

这将生成前缀的输出。现在,要按相反顺序排序,输出将传送到sort /r命令。

cmd /c"..." | sort /r 

由于管的结果需要被处理(在样品中,我们将只echo行到控制台)时,满管是for /f %%a(更^转义字符)内部执行。

for /f "tokens=1,* delims=¬" %%a in (' 
     cmd /c"..." ^| sort /r 
') do .... 

for命令指示¬字符将被用作分隔符来标记输入线(管执行的结果),并且我们要检索的第一令牌(数字前缀,即将不会被使用,但需要被包含)到%%a和该行的其余部分(没有额外的拆分)%%b

因此,在结束时,for /f %%ado子句中的代码将被用于在输入文件中的每一行,以相反的顺序执行,与存储在%%b行。

+0

是什么'delims =¬使用¬'的'” %%了'?,也可以请您解释一下您的解决方案的更多细节。 –

+1

@SubhamTripathi,答案更新。拜托,现在检查它是否 –

+0

哪个键是你要打印'¬',因为我没有在我的键盘上找到任何东西:) –

0

这反转了文件中的文本行。

交换

filter swap 

反转在一个文件中的线,所以顶线变为底线。

cscript //nologo filter.vbs swap <"%systemroot%\win.ini" 

从Filter.vbs从https://skydrive.live.com/redir?resid=E2F0CE17A268A4FA!121 - 用于与在文件中的行工作19样品VBS程序。它包含一个批处理文件,使用起来很方便。

Set Arg = WScript.Arguments 
set WshShell = createObject("Wscript.Shell") 
Set Inp = WScript.Stdin 
Set Outp = Wscript.Stdout 
    Dim LineCount 
    Set rs = CreateObject("ADODB.Recordset") 
    With rs 
     .Fields.Append "LineNumber", 4 
     .Fields.Append "Txt", 201, 5000 
     .Open 
     LineCount = 0 
     Do Until Inp.AtEndOfStream 
      LineCount = LineCount + 1 
      .AddNew 
      .Fields("LineNumber").value = LineCount 
      .Fields("Txt").value = Inp.readline 
      .UpDate 
     Loop 
     .Sort = "LineNumber DESC" 
     Do While not .EOF 
      Outp.writeline .Fields("Txt").Value 
      .MoveNext 
     Loop 
    End With 
+0

sry但我需要一个使用简单批处理的解决方案,感谢您的帮助:) –

相关问题