所以我的File1.txt包含内容
aaa
ccc
..和内容
的File2.txtaaa
bbb
ccc
我想从File2.txt中删除File1.txt中也有的所有行。所以在这个例子中,File2只剩下一行," bbb"
如何使用批处理文件实现此目的?
谢谢,
答案 0 :(得分:1)
for /f "tokens=*" %%a in (file1.txt) do (
REM We have to introduce a third file because we can't use the type command redirects its output to itself. this would result in an empty file
if exist file3.txt del file3.txt
TYPE file2.txt |find /i /v "%%a">file3.txt
COPY /y file3.txt file2.txt
)
仅当文件不引用字符(")时才有效,因为这可能会导致引用find /i /v "%%a"
神奇之处在于/v
命令的find
切换。它只显示不包含请求字符串的行。
答案 1 :(得分:0)
如果你能够在比较字符串时忽略大小写,那么使用FINDSTR就有一个简单的解决方案。
findstr /vlixg:"file1.txt" "file2.txt" >"file2.txt.new"
move /y "file2.txt.new" "file2.txt" >nul
如果File1.txt包含\\
或\"
,则上述操作无效。此类字符串必须以\\\
(或\\\\
)和\\"
(或\\\"
)进行转义。
搜索必须忽略大小写的原因是由于一个讨厌的FINDSTR错误:Why doesn't this FINDSTR example with multiple literal search strings find a match?
下面是一个强大的,区分大小写但缓慢的纯本机批处理解决方案,它一次从File1读取一行,并从File2中删除该行。它使用临时文件来保存搜索字符串。可以使用命令行上的搜索字符串来完成,除非有一个涉及\\
和\"
字符的模糊案例存在问题。有关详细信息,请参阅What are the undocumented features and limitations of the Windows FINDSTR command?中标题为在命令行文字搜索字符串中转义反斜杠的部分。
奇怪的FOR / F语法用于禁用EOL和DELIMS选项。仅当您将文件名更改为带空格的名称时,才会添加USEBACKQ选项。切换延迟扩展用于保护可能在File1中的!
个字符。
@echo off
setlocal disableDelayedExpansion
for /f usebackq^ delims^=^ eol^= %%A in ("File1.txt") do (
set "ln=%%A"
setlocal enableDelayedExpansion
(echo(!ln:\=\\!)>"File1.txt.new"
endlocal
findstr /vlxg:"File1.txt.new" "File2.txt" >"File2.txt.new"
move /y "File2.txt.new" "File2.txt" >nul
)
del "File1.txt.new" 2>nul
最后,如果您愿意使用某些混合脚本,那么以下内容非常强大,而且效率非常高。它依赖于hybrid JScript/batch utility called REPL.BAT来转义File1中的所有正则表达式元字符。
@echo off
type "File1.txt"|repl "([[\\.*^$])" \$1 >"File1.txt.new"
findstr /vrxg:"File1.txt.new" "File2.txt" >"File2.txt.new"
move /y "File2.txt.new" "File2.txt" >nul
del "File1.txt.new"