我有一个看起来像
的文本文件Line_A 123
Line_A 456
Line_A 789
Line_B 123
Line_B 456
Line_B 789
Line_C 123
Line_C 456
Line_C 789
一个看起来像这样的参考文件:
Line_A
Line_B
Line_C
我想从文本文件中提取与引用文件中的每个名称匹配的第一行,如下所示:
Line_A 123
Line_B 123
Line_C 123
到目前为止,我只能从第一场比赛获得第一行:
grep -A1 -w -f reference.txt -m 1 file.txt
也许我需要一个for循环? TIA
答案 0 :(得分:2)
另一个return CompareStr(k1->mValue, k2->mValue);
awk
将引用保留在一个集合中,当在文件中看到打印行并删除引用时,只会打印第一个实例。
答案 1 :(得分:1)
只要您在参数列表中首先列出参考文件,就可以在文件中单次传递,然后在Awk中执行此操作:
awk 'FNR == NR { name[$1] = 0; }
FNR != NR { for (i in name) if ($0 ~ i && name[i]++ == 0) { print $0; break; } }' \
reference.txt file.txt
使用样本输入,可以得到所需的输出。
这是Awk中相当标准的技术。您使用FNR == NR
条件读取第一个文件(文件行号等于总行号;仅对第一个文件中的行使用)并保存适当的信息供以后使用。通常,人们在第一行使用next
;有用。这意味着他们可以避免
FNR != NR
条件 - 我喜欢对称性。
处理第二个及后续文件时,检查从第一个文件读取的每个名称是否与一行匹配,并且之前没有打印过该名称,如果尚未处理,则打印该行。如果当前名称匹配,则中断避免检查其他名称。
这是许多人写命令的方式;它也有效。
awk 'FNR == NR { name[$1] = 0; next }
{ for (i in name) if ($0 ~ i && name[i]++ == 0) { print $0; break; } }' \
reference.txt file.txt
这里的代码的两个版本都在行中的任何地方查找名称;如果您严格要匹配第二个(或后续)文件的$1
,则可以更改条件(实际上,简化它们)。并且karakfa shows在匹配时删除匹配(而不是递增计数器),这对性能更好,因为您不必继续匹配不再相关的匹配。但是,此处显示的代码更容易适应显示给定名称的第二个,第三个或最后一个条目(处理第二个或第三个涉及将0更改为1或2;处理'last'需要更多实质性更改)。
答案 2 :(得分:1)
又一个awk:
$ awk 'a[$1]++==1' ref file
Line_A 123
Line_B 123
Line_C 123
按上述顺序读取这两个文件,计算第一列中的每个字符串,并在第二次看到时打印。如果file
中的字符串不在reference
中,则会失败。在这种情况下,使用其他解决方案之一。