我有一个文件1:
green
yellow
apple
mango
和file2:
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}'
我收到语法错误。
答案 0 :(得分: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}
,因此这是隐含的。
答案 1 :(得分:0)
你可以用bash,sed和grep:
来做grep -f <(sed 's/^/^/' file1) file2 | grep -f <(sed 's/$/$/' file1)
这有点模糊,所以我会将其分解:
grep -f <file>
从文件中读取一系列模式,并在任何模式上匹配。
<(...)
是bash
process substitution并执行shell命令并创建一个伪文件,其输出可用于代替文件名。
sed 's/^/^/' file1
在file1中每行的开头插入一个^
字符,将这些行转换为与file2的第一个单词匹配的模式。
sed 's/$/$/' file1
在末尾插入$
字符,因此模式将匹配第二个字。
修改强>: 使用:
grep -f <(sed 's/^/^/;s/$/\b/' file1) file2 | grep -f <(sed 's/$/$/;s/^/\b/' file1)
解决Jonathan在评论中指出的问题。
答案 2 :(得分: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
中的空格分隔列。