Unix 打印并匹配两个文件之间两列匹配的行
我想匹配文件中的第1列和第2列,以便与路径中不同目录中的文件和名为/.file的文件匹配,并打印与这些列匹配的整行 /.file(示例) 用于匹配Unix 打印并匹配两个文件之间两列匹配的行,unix,awk,match,Unix,Awk,Match,我想匹配文件中的第1列和第2列,以便与路径中不同目录中的文件和名为/.file的文件匹配,并打印与这些列匹配的整行 /.file(示例) 用于匹配 carrot 124555 输出 carrot 124555 1 2 6 现在,我可以将第1列与这两个列进行匹配 for i in */*.file; do awk -F, 'FNR==NR {a[$1]=$0; next}; $1 in a {print a[$1]}' $i for_matching > $i.matched; done
carrot 124555
输出
carrot 124555 1 2 6
现在,我可以将第1列与这两个列进行匹配
for i in */*.file; do awk -F, 'FNR==NR {a[$1]=$0; next}; $1 in a {print a[$1]}' $i for_matching > $i.matched; done
使用awk
awk 'FNR==NR{arr[$1,$2];next}(($1,$2) in arr)' for_matching file
测试结果:
$ cat file
carrot 124555 1 2 6
hair 9922 2 2 2
tree 2223 2 1 2
$ cat for_matching
carrot 124555
$ awk 'FNR==NR{arr[$1,$2];next}(($1,$2) in arr)' for_matching file
carrot 124555 1 2 6
与多个文件相同,不需要ls*/*.file
#!/usr/bin/env bash
for i in */*.file; do
awk 'FNR==NR{arr[$1,$2];next}(($1,$2) in arr)' for_matching "$i" >"$i.matched"
done
这非常简单,您可以:
$ grep -F -w -f for_matching file
carrot 124555 1 2 6
有关限制,请参见下文@karakfa的评论
这当然可以通过以下方法来避免:
$cat文件
胡萝卜124555126
1胡萝卜124555 1 2 6
$grep-w-f请使用globs,而不是ls
来循环文件:用于*/*.文件中的i
并在2018年停止使用反勾号,首选$()
您不需要for循环,awk
可以读取多个文件awk…formatching*.file
。这将避免您运行多个awk
进程….@karakfa是的,但从OP post来看,OP似乎希望在单个文件中保存匹配的记录有打印>文件名“.matched”
。@karakfa可能是。是否还要打印文件中不匹配的行以进行匹配?还是空白行?如果字段2-
上出现相同的一对,则这将匹配。这是一个危险的答案,因为它看起来很简单,并且会从某些特定的样本输入中产生预期的输出,但随后会出现错误“我会悄悄地咬你的屁股,当你指望它时,给你不同的输入。@埃德蒙顿,这就是为什么我认为我应该坚持awk答案-我的文件有1300万行长,我有500行,所以我会比较这和awk答案之间的输出!只是要知道批量输入不能替代经过考虑的输入。你的1300万行行可能没有任何问题,但这并不意味着没有问题,也不意味着接下来的10行可能会爆炸。认真想想这段代码在做什么,你将能够想出导致它失败的测试用例。例如,如果For_matching
只包含单词carrot
alo,请尝试这个和awk解决方案ne或以car.ot
开始,而不是carrot
,或者…@EdMorton你当然是对的。后面的部分只是一个笑话(因此是笑脸:)并且@karakfa的评论仍然有效。感谢
的提醒,我忘了添加-F
。
$ grep -F -w -f for_matching file
carrot 124555 1 2 6
$ cat file
carrot 124555 1 2 6
1 carrot 124555 1 2 6
$ grep -w -f <(sed 's/^/^/g' for_matching) file
carrot 124555 1 2 6