如何使用批处理以自下而上的方式读取文本文件

时间:2015-04-23 06:10:56

标签: batch-file cmd

我正在开发一个需要创建某些资源的项目,同时创建资源我也会在文件中写入,以便在发生错误时回滚该创建过程。 但是这里有一个问题,资源必须以与创建它们相反的方式删除,所以当我写回滚文件时这样:

delete R1
delete R2
..
..
delete RN

我想按顺序删除资源 - >

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

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

2 个答案:

答案 0 :(得分:3)

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

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

@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命令回应了计算结果,因此我们不需要这样做,并且延迟扩展问题消失了。我们只计算新的计数器(得到回声),并回显分隔符和从输入文件中读取的行。所以我们有以下代码

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

它被编写为连接命令并作为参数传递给cmd实例(注意:^用于转义有问题的字符),这是用echo off执行的({{ 1}}),已启用扩展程序(/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的{​​{1}}子句中的代码将以相反的顺序对输入文件中的每一行执行,并且行存储在{{1}中}。

答案 1 :(得分:0)

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

<强>交换

filter swap

反转文件中的行,使顶行成为底线。

示例

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

来自https://skydrive.live.com/redir?resid=E2F0CE17A268A4FA!121的Filter.vbs - 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