GNU 并行处理器与 xargs 和 awk 的使用

4

我有两个大的制表符分隔的文件A.tsv和B.tsv,它们看起来像这样(文件中没有标题):

A.tsv:  
ID AGE  
User1  18   
...

B.tsv:  
ID INCOME  
User4  49000  
...

我想在A表中选择年龄在10到20岁之间的ID列表,并选择在B表中匹配该列表的行。同时,我想使用GNU parallel工具。我的尝试分为两步:

cat A.tsv | parallel --pipe -q awk '{ if ($3 >= 10 && $3 <= 20) print $1}' > list.tsv

cat list.tsv | parallel --pipe -q xargs -I% awk 'FNR==NR{a[$1];next}($1 in a)' % B.tsv > result.tsv

第一步可以正常运作,但第二步出现了错误,如下所示:
awk: cannot open User1 (No such file or directory)

我该如何解决这个问题?即使 A.tsv 和 list.tsv 的大小是内存的两到三倍,这种方法仍然有效吗?


你的 list.tsv 文件中是否存在 'User1' 这个单词?如果不存在,为什么会出现这个问题呢?祝好运。 - shellter
是的,在文件中存在“User1”这个词,但不包含ID、AGE或INCOME等标题行,我猜这是因为GNU parallel的--pipe参数在第二步中无法工作,并将输出视为文件名参数而不是stdin,我不知道为什么。 - Bamqf
虽然我非常欣赏简短的示例文件,但是不清楚你为什么需要并行和xargs。假设你没有处理几TB数据,使用awk构建一个一行命令应该很容易实现你想要的功能。祝好运! - shellter
2个回答

4
$ for I in $(seq 8 2 22); do echo -e "User$I\t$I" >> A.txt; done; cat A.txt
User8   8
User10  10
User12  12
User14  14
User16  16
User18  18
User20  20
User22  22

$ for I in $(seq 8 2 22); do echo -e "User$I\t100${I}00" >> B.txt; done; cat B.txt
User8   100800
User10  1001000
User12  1001200
User14  1001400
User16  1001600
User18  1001800
User20  1002000
User22  1002200

$ cat A.txt | parallel --pipe -q awk '{if ($2 >= 10 && $2 <= 20) print $1}' > list.txt
$ cat B.txt | parallel --pipe -q grep -f list.txt
User10  1001000
User12  1001200
User14  1001400
User16  1001600
User18  1001800
User20  1002000

谢谢,但我需要一种能够实现并行计算的解决方案。 - Bamqf
我添加了 parallel --pipe -q - user32

0
我知道这个:(是的,我看到了) GNU parallel 与 xargs 和 awk 一起使用 8年3个月前提问 8年3个月前修改 已查看2k次
我的解决方案: 只用xargs和awk,只有一行而不需要中间文件,也不需要安装新工具。
awk '{if ($2 >= 10 && $2 <= 20) print $1}' A.tsv | xargs -I myItem awk --assign quebuscar=myItem '$1==quebuscar {print}' B.tsv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接