如何使用批处理以自下而上的方式读取文本文件
How to read a text file in bottom up manner using batch
我正在做一个需要创建某些资源的项目,在创建资源的同时,我还写在一个文件中,以便在发生错误时回滚该创建过程。
但是这里有一个问题,必须以与创建资源相反的方式删除资源,所以当我这样写回滚文件时:
delete R1
delete R2
..
..
delete RN
我想按顺序删除资源 ->
delete RN
delete RN-1
....
...
delete R1
有没有办法在 windows 批处理中做到这一点?
没有使用批处理以相反顺序读取文件的本机方法。
但是,虽然不是最快的方法,但可以解决以正常顺序读取文件、在每一行前面加上一个填充数字、以相反顺序对列表进行排序、拆分行以分隔数字然后处理名单
@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"
,但要在循环中回显它,我们将需要延迟扩展,但这可能会导致从文件读取的数据出现问题(我不知道它是否可以包含 !
个字符)。
我们可以enable/disable延迟扩展来处理,但是因为每行都需要这样,所以会有性能损失。为了解决这个问题,代码在一个单独的 cmd
实例中执行。
为什么要一个单独的实例?这个单独实例中的代码不是在批处理上下文中执行的,而是在命令行上下文中执行的。在命令行上下文中,set /a
命令会回显计算结果,因此我们不需要这样做,延迟扩展问题就消失了。我们简单地计算新的计数器(得到回显),并回显分隔符和从输入文件中读取的行。所以我们有下面的代码
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 %%a
的do
子句中的代码将对输入文件中的每一行执行,以相反的顺序,与存储在[=中的行34=].
这会反转文件中的文本行。
交换
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
我正在做一个需要创建某些资源的项目,在创建资源的同时,我还写在一个文件中,以便在发生错误时回滚该创建过程。 但是这里有一个问题,必须以与创建资源相反的方式删除资源,所以当我这样写回滚文件时:
delete R1
delete R2
..
..
delete RN
我想按顺序删除资源 ->
delete RN
delete RN-1
....
...
delete R1
有没有办法在 windows 批处理中做到这一点?
没有使用批处理以相反顺序读取文件的本机方法。
但是,虽然不是最快的方法,但可以解决以正常顺序读取文件、在每一行前面加上一个填充数字、以相反顺序对列表进行排序、拆分行以分隔数字然后处理名单
@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"
,但要在循环中回显它,我们将需要延迟扩展,但这可能会导致从文件读取的数据出现问题(我不知道它是否可以包含 !
个字符)。
我们可以enable/disable延迟扩展来处理,但是因为每行都需要这样,所以会有性能损失。为了解决这个问题,代码在一个单独的 cmd
实例中执行。
为什么要一个单独的实例?这个单独实例中的代码不是在批处理上下文中执行的,而是在命令行上下文中执行的。在命令行上下文中,set /a
命令会回显计算结果,因此我们不需要这样做,延迟扩展问题就消失了。我们简单地计算新的计数器(得到回显),并回显分隔符和从输入文件中读取的行。所以我们有下面的代码
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 %%a
的do
子句中的代码将对输入文件中的每一行执行,以相反的顺序,与存储在[=中的行34=].
这会反转文件中的文本行。
交换
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