使用bash脚本从文件中删除字符串

时间:2014-10-27 20:09:09

标签: linux bash

我想从文件中删除特定字符串。 我尝试使用:

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

4 个答案:

答案 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
  1. 在sed命令中转换2.txt中的每一行,例如abc - > -e /^abc$/d
  2. 将sed命令列表提供给在4.txt上运行的sed实例
  3. 要将输出存储回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;开头。选项。