我有两个文件。
file.txt
和delete.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)