我似乎无法使用 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