1

我有一个文件1:

green
yellow
apple
mango

和一个文件2:

red apple
blue banana
yellow mango
purple cabbage

我需要从 file2 中找到两个单词都属于 file1 中的列表的元素。所以它应该显示:

黄芒果

我试过了:

awk < file2 '{if [grep -q $1 file1] && [grep -q $2 file1]; then print $0; fi}'

我收到语法错误。

4

3 回答 3

3

这可以解决问题:

$ awk 'NR==FNR{a[$0];next}($1 in a)&&($2 in a)' file1 file2 
yellow mango

解释:

NR是一个特殊awk变量,它跟踪输入中的FNR当前行并跟踪每个单独文件中的当前行,因此NR==FNR仅当我们在第一个文件中时条件才成立。a是一个关联数组,其中键是第一个文件中的每个唯一行。$0是当前行的值awk。语句跳转到文件中的next下一行以跳过不执行的下一部分。$1如果第一个字段在数组中,则最后一部分是直截了当的a,然后第二个字段打印当前行。默认块awk{print $0}所以这是隐式的。

于 2013-04-23T16:58:13.510 回答
0

这是一种非常骇人听闻的方法,并且可能被许多 grep/sed 实现者所反对。此外,它可能取决于终端。你被警告了。

GNU grep 在颜色模式下会突出显示与其中一种模式匹配的输入片段,这在理论上可以用作完全匹配的测试。在这里,这甚至可以在实践中使用,也就是说,在 GNU sed 的帮助下:

grep --color=always -f file1 file2 | sed -n '/^\x1b.*\x1b\[K *\x1b.*\x1b\[K$/ { s/\x1b\[K//g; s/\x1b[^m]*m//gp }'

输出:

yellow mango

请注意,sed 模式假定file2.

于 2013-04-23T19:25:16.127 回答
0

您可以使用 bash、sed 和 grep 来完成:

grep -f <(sed 's/^/^/' file1) file2  | grep -f <(sed 's/$/$/' file1)

这有点晦涩难懂,所以我将其分解:

grep -f <file>从文件中读取一系列模式并将匹配其中任何一个。

<(...)bash 进程替换,将执行 shell 命令并创建一个伪文件,其输出可用于代替文件名。

sed 's/^/^/' file1在 file1 的每一行的开头插入一个^字符,将这些行转换为匹配 file2 的第一个单词的模式。

sed 's/$/$/' file1$在末尾插入一个字符,因此模式将匹配第二个单词。

编辑:使用:

grep -f <(sed 's/^/^/;s/$/\b/' file1) file2  | grep -f <(sed 's/$/$/;s/^/\b/' file1)

绕过乔纳森在评论中指出的问题。

于 2013-04-23T17:01:10.120 回答