是否可以使用 grep 或 awk 报告与索引文件中的重复条目相对应的重复输出行?

是否可以使用 grep 或 awk 报告与索引文件中的重复条目相对应的重复输出行?

我似乎无法使用 grep 或 awk 来对列表进行相对简单的索引拉取。我怀疑这是因为索引文件中存在相邻的重复项,我认为这不会导致问题。奇怪的是,在网上寻找解决方案并不成功,因为我发现的所有查询都是想要删除重复项而不是保留重复项的人!

索引文件看起来像这样,有大约 40k 条目,其中许多是重复排序的:

n0000003
n0000003
n0000008
n0000008
n0000017
n0000017
n0000017
n0000017
.....etc

搜索文件如下所示,每个标识符有大约 10k 个唯一条目:

n0000003    216 -0.334  0.229   0.088   0.154
n0000008    16  0.117   0.200   0.508   0.621
n0000017    218 -0.353  0.196   0.042   0.084
...etc

我需要的是这样的输出,重复输出条目等于索引文件中重复索引条目的数量:

n0000003    216 -0.334  0.229   0.088   0.154
n0000003    216 -0.334  0.229   0.088   0.154
n0000008    16  0.117   0.200   0.508   0.621
n0000008    16  0.117   0.200   0.508   0.621
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084
...etc

但 grep 和 awk 都只给出一个条目(使其与搜索文件相同)。我认为 grep 可以毫无问题地处理重复的重复项,但我找不到解决方法。

这些是我期望起作用的命令,例如:

grep -f index.txt searchfile.txt > output.txt
awk -F'\t' 'NR==FNR{c[$1]++;next};c[$1]' index.txt searchfile.txt > output.txt

任何关于如何让 grep 或 awk 输出正确的重复次数的建议都会很棒!非常感谢!安德鲁

答案1

我认为你不能用grep, 不,但你可以用 来做到这一点awk。我能想到的最简单的方法是将 的内容存储searchfile.txt在内存中,然后每次看到索引时打印其行:

$ awk -F'\t' 'NR==FNR{c[$1]=$0;next}{if(c[$1]){print c[$1]}}' searchfile.txt index.txt 
n0000003    216 -0.334  0.229   0.088   0.154
n0000003    216 -0.334  0.229   0.088   0.154
n0000008    16  0.117   0.200   0.508   0.621
n0000008    16  0.117   0.200   0.508   0.621
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084

如果两个文件都在索引上排序,您还可以使用join

$ join -t$'\t' searchfile.txt index.txt 
n0000003    216 -0.334  0.229   0.088   0.154
n0000003    216 -0.334  0.229   0.088   0.154
n0000008    16  0.117   0.200   0.508   0.621
n0000008    16  0.117   0.200   0.508   0.621
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084
n0000017    218 -0.353  0.196   0.042   0.084

答案2

看看你的尝试,你似乎几乎接近球门柱,但没有让足球越过它,只是在你的尝试中添加了一个 while 循环。

awk -F'\t' '
  FNR == NR { c[$1]++; next }
  k = c[$1] { while (k--) print }
' index.txt search.txt

相关内容