要从文件中删除的模式列表

要从文件中删除的模式列表

为了进一步说明,我们有两个文件内容:

文件1

hello
1_hello 
2_hello
world
1_world
2_world
hello1
1_hello1
2_hello1
world1
1_world1
2_world1

文件2

This
hello
1_hello
2_hello
is world
1_world
2_world
my
hello1
1_hello1
2_hello1
word
world1
1_world1
2_world1
file 

我想要的是迭代文件 1 的第一列并删除文件 2 中匹配的条目并产生如下输出:

This
is
my 
word
file

我该怎么办?

答案1

你想使用 awk 读取 file1 并记住其中的所有单词。然后读取 file2 并输出 file1 中未见过的任何单词:

gawk -v RS='[[:space:]]+' 'NR==FNR {words[$1]=1; next} !($1 in words)' file1 file2

它使用任意空格序列作为记录分隔符,因此每个单词都被视为单独的“行”。这现在是 GNU awk 特有的,但这是 Ubuntu 上的默认 awk

答案2

您可以使用grep -f FILE从文件中获取模式FILE。对于您的情况,我建议在以下最终grep调用中使用一些附加标志(请参阅下面的说明):

grep -v -x -F -f file1 -- file2
  • -f FILE– 从中获取模式FILE,每行一个。

  • -F– 将模式解释为固定字符串列表,以换行符分隔,其中任何一个都可以匹配。

  • -x– 仅选择与整行完全匹配的匹配项。(如果您想允许部分匹配的行,则可能需要删除此选项。)

  • -v– 反转匹配的方向,以选择不匹配的线。

资料来源:GNU grep 文档或者手册页

上面使用的所有选项均由 POSIX 指定,不需要 GNU 扩展。

答案3

这个命令行应该可以解决问题:

while read -r word; do sed -e "s/\<$word\>//g" -e '/^\s*$/d' file2 -i; done < file1

执行上述命令后,输出文件——file2应该如下所示:

This
is
my
word
file

上述命令行的更易读的版本:

while read -r word; do \
    sed -e "s/\<$word\>//g" -e '/^\s*$/d' file2 -i; \
done < file1

循环while逐行读取文件 - < file1。每行的值用作临时创建的变量的值,称为$word- -r word。此变量用作命令中的参数,并在 [ ] 中用空白值sed替换,即第一个表达式:= 。标志表示 - 将替换应用于所有匹配项。然后,如果文件中有空白行,则会将其删除 - 第二个表达式:。sfile2"s/\<$word\>//g"s/<source_value>/<replacement_value>/gg'/^\s*$/d'

我们需要使用语法来查找精确匹配。第一个表达式\<...\>需要双引号 - - ,因为它是变量的名称,我们希望在命令中将其扩展为其值。"..."$wordsed

选项-i表示更改将在目标文件内进行 - file2。如果删除此选项,结果将抛出到 stdout,但这没有任何意义。此选项-i.bak不适用于这种情况,因为目标文件将被多次覆盖,因此您应该提前创建备份副本。

答案4

虽然删除标准不是很清楚,但我假设要删除的部分是(www\n1_www\n2_www)对于所有单词www(如果我错了,请纠正我)

使用(gnu)sed:

sed -zr 's/(\w+)\n1_\1\n2_\1\n//g' ex

相关内容