我有一个包含以下内容的文本文件:
ABC 1 XYZ 1 QWE 1 GRE 1 脱硫剂2 德国2号 输出2 RTY 3 兴趣点3 移动NB 3 LKJ 3
预期输出:
ABC XYZ QWE GRE DGD 格尔输出 RTY POI MNB LKJ
即,具有相同第二列值的所有单词应出现在同一行中,并用一个空格分隔。
答案1
使用任何 awk 并按照输入中出现的顺序打印输出记录,并且不将所有输入读取到内存中:
$ awk '
$2 != prev { if (NR>1) print rec; rec=$1; prev=$2; next }
{ rec = rec OFS $1 }
END { print rec }
' file
ABC XYZ QWE GRE
DGD GER OUT
RTY POI MNB LKJ
上面假设您的输入按示例输入中所示的第二个字段值进行分组,如果情况并非如此,则只需先对它们进行排序 -sort -k2,2 file | awk 'script'
上面只是将 $2 的 $1 集合存储在内存中,因为每个 $2 都出现在输入中,如果您甚至不想这样做,您可以在 $1 出现时打印它们:
$ awk '
$2 != prev { if (NR>1) print ""; printf "%s", $1; prev=$2; next }
{ printf "%s%s", OFS, $1 }
END { print "" }
' file
ABC XYZ QWE GRE
DGD GER OUT
RTY POI MNB LKJ
答案2
类似的东西可以完成这项工作:
awk '{a[$2]=a[$2]" "$1} END {for (i in a) print substr(a[i],2)}'
用于substr
删除前导空格
答案3
使用磨坊主( mlr
) 处理无标头的“漂亮打印”(空格分隔)数据:
$ mlr --pprint -N nest --ivar ' ' -f 1 then cut -f 1 file
ABC XYZ QWE GRE
DGD GER OUT
RTY POI MNB LKJ
这将使用 Miller 操作折叠第一个字段中的条目nest
,并按第二个字段中的数据进行分组。折叠的条目将由空格(命令行上单引号中的字符)分隔。第二个操作 ,cut
仅提取折叠字段。
答案4
使用datamash
:
$ datamash -sW groupby 2 collapse 1 --collapse-delimiter ' ' <file | datamash cut 2
关于折叠分隔符,请参阅其手册:
--collapse-delimiter=x
-c x
Use character X instead of comma to delimit items in a ‘collapse’ or ‘unique’ (aka ‘uniq’) list.