批处理脚本 - 从文本文件中删除特定行
Batch Script - Deleting specific lines from a text file
假设有两个文件 Temp1 和 Temp2 包含以下数据 =
Temp1.txt:
xxxx xxxxx xxxxxxxx xxxxx xxxxx
yyyyy yyyy yyy yyyyyyy yyyy yyy
zz zzzzz zz zzzz zzz zzz zz z z
Temp2.txt :
xxxx xxxxx xxxxxxxx xxxxx xxxxx
zz zzzzz zz zzzz zzz zzz zz z z
aaaa aa aaaa aa aaaaa aaa aaaaaa
要求是删除(在Temp1中)与Temp2匹配的行。并可能将其保存在不同的文件中。
所以,基本上输出应该是这样的:
Temp.txt :
yyyyy yyyy yyy yyyyyyy yyyy yyy
这是我目前得到的:
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "Delims=" %%A IN ('type "Temp2.txt"') DO (
SET STRING=%%A
FINDSTR /V /C:%STRING% "Temp1.txt" > Temp.txt
)
但是,我认为这段代码会保留匹配的数据,而不是删除。需要更正。
您甚至不需要为此编写脚本。这是一个命令:
findstr /x /v /G:temp2.txt temp1.txt >temp.txt
/x
比较整行
/v
只打印不匹配
的行
/g
使用文件 (temp2.txt) 获取搜索字符串
FINDSTR 本身应该是一个很好的解决方案。阅读文档,人们会认为以下文字搜索应该有效。
findstr /vlxg:"temp2.txt" "temp1.txt" >temp.txt
但是下面的FINDSTR bugs and limitations让上面的不可靠
- Specifying multiple literal search strings can fail to find all matches(错误)
- 文字搜索可能需要
\
and/or "
转义为 \
和 \"
解决方案是改用正则表达式搜索。但这要求必须转义 temp2.txt 内的正则表达式元字符。这对我的 JREPL.BAT regular expression find/replace utility 来说是一项完美的任务。 JREPL.BAT 是一个混合 JScript/batch 脚本,可以在任何 Windows XP 以后的机器上本地运行。
jrepl "[.*^$[\]" "$&" /f "temp2.txt"|findstr /rvxg:/ "temp1.txt" >"temp.txt"
以上工作原理如下
JREPL 命令转义 temp2.txt 内的元字符,输出通过管道传输到 FINDSTR
FINDSTR /R 选项将所有搜索字符串视为正则表达式
/V 选项导致匹配行被抑制,不匹配的行被打印
/X 选项表示搜索字符串必须匹配整行
/G:/ 选项指示 FINDSTR 从标准输入(管道)读取搜索字符串
JREPL | FINDSTR 解决方案具有以下限制,全部归因于 FINDSTR 行为
- temp2.txt 中的所有行必须 <= 511 个字符,即使在转义元字符后也是如此
- temp1.txt 中的所有行必须由 \r\n 终止(回车 return 换行)
- \r 不得出现在 temp1.txt 内的任何位置,但行尾除外。
如果您下载 GNU grep for Windows - 标准 unix 实用程序的一个端口,可以消除限制,解决方案会简单得多。
grep -x -v -F -f "temp2.txt" "temp1.txt" >"temp.txt"
假设有两个文件 Temp1 和 Temp2 包含以下数据 =
Temp1.txt:
xxxx xxxxx xxxxxxxx xxxxx xxxxx
yyyyy yyyy yyy yyyyyyy yyyy yyy
zz zzzzz zz zzzz zzz zzz zz z z
Temp2.txt :
xxxx xxxxx xxxxxxxx xxxxx xxxxx
zz zzzzz zz zzzz zzz zzz zz z z
aaaa aa aaaa aa aaaaa aaa aaaaaa
要求是删除(在Temp1中)与Temp2匹配的行。并可能将其保存在不同的文件中。 所以,基本上输出应该是这样的:
Temp.txt :
yyyyy yyyy yyy yyyyyyy yyyy yyy
这是我目前得到的:
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "Delims=" %%A IN ('type "Temp2.txt"') DO (
SET STRING=%%A
FINDSTR /V /C:%STRING% "Temp1.txt" > Temp.txt
)
但是,我认为这段代码会保留匹配的数据,而不是删除。需要更正。
您甚至不需要为此编写脚本。这是一个命令:
findstr /x /v /G:temp2.txt temp1.txt >temp.txt
/x
比较整行
/v
只打印不匹配
/g
使用文件 (temp2.txt) 获取搜索字符串
FINDSTR 本身应该是一个很好的解决方案。阅读文档,人们会认为以下文字搜索应该有效。
findstr /vlxg:"temp2.txt" "temp1.txt" >temp.txt
但是下面的FINDSTR bugs and limitations让上面的不可靠
- Specifying multiple literal search strings can fail to find all matches(错误)
- 文字搜索可能需要
\
and/or"
转义为\
和\"
解决方案是改用正则表达式搜索。但这要求必须转义 temp2.txt 内的正则表达式元字符。这对我的 JREPL.BAT regular expression find/replace utility 来说是一项完美的任务。 JREPL.BAT 是一个混合 JScript/batch 脚本,可以在任何 Windows XP 以后的机器上本地运行。
jrepl "[.*^$[\]" "$&" /f "temp2.txt"|findstr /rvxg:/ "temp1.txt" >"temp.txt"
以上工作原理如下
JREPL 命令转义 temp2.txt 内的元字符,输出通过管道传输到 FINDSTR
FINDSTR /R 选项将所有搜索字符串视为正则表达式
/V 选项导致匹配行被抑制,不匹配的行被打印
/X 选项表示搜索字符串必须匹配整行
/G:/ 选项指示 FINDSTR 从标准输入(管道)读取搜索字符串
JREPL | FINDSTR 解决方案具有以下限制,全部归因于 FINDSTR 行为
- temp2.txt 中的所有行必须 <= 511 个字符,即使在转义元字符后也是如此
- temp1.txt 中的所有行必须由 \r\n 终止(回车 return 换行)
- \r 不得出现在 temp1.txt 内的任何位置,但行尾除外。
如果您下载 GNU grep for Windows - 标准 unix 实用程序的一个端口,可以消除限制,解决方案会简单得多。
grep -x -v -F -f "temp2.txt" "temp1.txt" >"temp.txt"