批量逐行读取File1,如果找到匹配的行,则从File2中删除它们

时间:2014-08-04 12:05:14

标签: batch-file

所以我的File1.txt包含内容

aaa
ccc

..和内容

的File2.txt
aaa
bbb
ccc

我想从File2.txt中删除File1.txt中也有的所有行。所以在这个例子中,File2只剩下一行," bbb"

如何使用批处理文件实现此目的?

谢谢,

2 个答案:

答案 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"