根据第二列对数据进行分组

根据第二列对数据进行分组

我有一个包含以下几行的文件:

1 a
2 a
3 a
1 b
2 b
1 c
2 c
3 c
4 c
1 d

我想得到的结果是:

a 1 2 3
b 1 2
c 1 2 3 4
d 1

答案1

使用awk

awk '{ group[$2] = (group[$2] == "" ? $1 : group[$2] OFS $1 ) }
     END { for (group_name in group) print group_name, group[group_name] }' inputfile

这会将组存储在名为 的数组中group。该数组根据组名称(输入数据中的第二列)进行索引,并且对于 的每一行输入inputfile,第一列中的值将附加到正确的组中。

END块循环遍历所有收集的组并输出组名称和该组的条目。

awk程序具有更好的布局:

{
    group[$2] = (group[$2] == "" ? $1 : group[$2] OFS $1 )
}

END {
    for (group_name in group)
        print group_name, group[group_name]
}

请注意,这是不是group如果数组实际存储大量数据,您想要做什么全部从文件中读取的输入数据。

对于海量数据,我们假设输入是已排序在组名称(第二列)上并使用

awk '$2 != group_name { if (group != "") print group_name, group; group = ""; group_name = $2 }
    { group = (group == "" ? $1 : group OFS $1) }
    END { if (group != "") print group_name, group }' inputfile

这会跟踪当前组是什么,并收集该组的数据。每当输入中的第二列切换到另一个值时,它就会输出收集的组数据并开始收集新数据。这意味着仅存储几行输入,而不是存储整个输入数据集。

最后一个awk程序有更好的布局:

$2 != group_name {
    if (group != "")
        print group_name, group

    group = ""
    group_name = $2
}

{
    group = (group == "" ? $1 : group OFS $1)
}

END {
    # Output last group (only), if there was any data at all.
    if (group != "")
        print group_name, group
}

答案2

尝试这个,

for i in  `awk '!a[$2]++ { print $2}' file.txt`
do
        echo "$i `awk -v z=$i '$2==z{print $1}' file.txt | tr '\n' ' '`"
done
  • awk '!a[$2]++ { print $2}将给出第 2 列的唯一值。
  • $2==z{print $1}将打印 $2 等于变量的所有值z

答案3

命令:for i in a b c d; do echo $i;awk -v i="$i" '$2 == i{print $1}' filename| perl -pne "s/\n/ /g";echo " "| perl -pne "s/ /\n/g";done| sed '/^$/d'| sed "N;s/\n/ /g"

输出

for i in a b c d; do echo $i;awk -v i="$i" '$2 == i{print $1}' l.txt | perl -pne "s/\n/ /g";echo " "| perl -pne "s/ /\n/g";done| sed '/^$/d'| sed "N;s/\n/ /g"

a 1 2 3 
b 1 2 
c 1 2 3 4 
d 1

相关内容