Unix 打印并匹配两个文件之间两列匹配的行

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

我想匹配文件中的第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
使用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