我想从文件中删除特定字符串。 我尝试使用:
for line3 in $(cat 2.txt)
do
if grep -Fxq $line3 4.txt
then
sed -i /$line3/d 4.txt
fi
done
我希望这段代码从4.txt删除行,如果它们也在2.txt中,但是这个循环删除了4.txt中的所有行,我不明白为什么。有人能说出这段代码有什么问题吗?
2.txt:
a
ab
abc
4.txt:
a
abc
abcdef
答案 0 :(得分:1)
您可以通过单awk command
:
awk 'ARGV[1] == FILENAME && FNR==NR {a[$1];next} !($1 in a)' 2.txt 4.txt
abcdef
要将输出存储回4.txt
,请使用:
awk 'ARGV[1] == FILENAME && FNR==NR {a[$1];next} !($1 in a)' 2.txt 4.txt > _tmp && mv _tmp 4.txt
PS:已添加ARGV[1] == FILENAME &&
以处理空文件案例,如下面@pjh所述。
答案 1 :(得分:1)
grep -F -v -x -f 2.txt 4.txt
或
grep -Fvxf 2.txt 4.txt
或
fgrep -vxf 2.txt 4.txt
答案 2 :(得分:0)
看马',只有sed ......
sed $( sed 's,^, -e /^,;s,$,$/d,' 2.txt ) 4.txt
2.txt
中的每一行,例如abc
- > -e /^abc$/d
要将输出存储回4.txt,请使用:
sed -i $( sed 's,^, -e /^,;s,$,$/d,' 2.txt ) 4.txt
编辑:虽然我喜欢我在美学基础上的答案,但请勿尝试 这在家里!请参阅下面的pjh评论,了解详细的理由 我的微博可能失败的很多方式
答案 3 :(得分:0)
只使用Bash(4)内置:
declare -A found
while IFS= read -r line || [[ $line ]] ; do found[$line]=1 ; done <2.txt
while IFS= read -r line || [[ $line ]] ; do
(( ${found[$line]-0} )) || printf '%s\n' "$line"
done <4.txt
&#39; [[$ line]]&#39;测试是处理具有未终止的最后一行的文件。
使用&#39; printf&#39;而不是回声&#39;如果任何输出行以&#39; echo&#39;开头。选项。