需要根据另一列值将列转换为行格式

需要根据另一列值将列转换为行格式

我有一个包含以下内容的文本文件:

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.

相关内容