Bash – 从一个文件中删除行,同时迭代另一个文件中的行

我有两个文件。

file.txtdelete.txt

file.txt包含以下内容:

 /somedirectory/ /somedirectory2/somefile.txt /anotherfile.txt 

delete.txt包含:

 /somedirectory/ /somedirectory2/somefile.txt 

我需要删除delete.txt中包含的file.txt中的行

cat file.txt应该导致:

 /anotherfile.txt 

到目前为止,我已经试过这个没有运气:

 while read p; do line=$p; sed -i '/${line}/d' file.txt; done < delete.txt 

我没有收到任何错误,它只是不编辑我的file.txt文件。 我已经用echo ${line}testing了while循环,并且在该场景中按预期工作。

有什么build议么?

注意:上面的while循环不能按预期的方式工作,即使在我把文件的正斜杠去掉的时候也是如此。

用简单的grep

 grep -vFxf delete.txt file.txt > temp.txt && mv temp.txt file.txt 

awk

 awk 'NR==FNR {a[$0]=1; next}; !a[$0]' delete.txt file.txt 
  • NR==FNR {a[$0]=1; next} NR==FNR {a[$0]=1; next}仅对delete.txt文件(第一个文件参数)执行; 关联数组a具有记录作为关键字, 1作为每个关键字的值

  • !a[$0]为第二个文件参数执行!a[$0] ,即file.txt ; 打印(默认动作)数组a中不存在的记录作为键(s)

例:

 % cat delete.txt /somedirectory/ /somedirectory2/somefile.txt % cat file.txt /somedirectory/ /somedirectory2/somefile.txt /anotherfile.txt % awk 'NR==FNR {a[$0]=1; next}; !a[$0]' delete.txt file.txt /anotherfile.txt 

单引号内的$ {line}不会被扩展,因此它将在file.txt中查找实际的字符串$ {line}。 把它放到你的示例文件中,看看它是否被删除。

但是,您仍然会遇到问题,因为删除文本内的斜杠会被sed解释,所以正则表达式不会被正确分隔。 为了使用sed,你必须跳过一些箍环才能将输入行中的每个字符正确引用为文字。

改用comm

 comm -23 file.txt delete.txt 

但是输入文件必须被排序。 如果他们不是:

 comm -23 <(sort file.txt) <(sort delete.txt)