Perl 按照第1列中的值排列列中的值

Perl 按照第1列中的值排列列中的值,perl,unix,awk,sed,solaris,Perl,Unix,Awk,Sed,Solaris,我有一个包含以下数据的文件 cat text.txt 281475473926267,46,47 281474985385546,310,311 281474984889537,248,249 281475473926267,16,17 281474985385546,20,28 281474984889537,112,68 第1列中的值在某些位置重复 我要如下所示的付款交单 cat output.txt 281475473926267 16,17,46,47 281474985385546

我有一个包含以下数据的文件

cat text.txt
281475473926267,46,47
281474985385546,310,311
281474984889537,248,249
281475473926267,16,17
281474985385546,20,28
281474984889537,112,68
第1列中的值在某些位置重复 我要如下所示的付款交单

cat output.txt
281475473926267 16,17,46,47
281474985385546 20,28,310,311
281474984889537 68,112,248,249
它应该先打印第1列的uniq值,然后打印空格,然后在一行中按升序打印其他列的相应值

cat text.txt | perl -F, -lane ' $kv{$F[0]}{$F[1]}++; END { while(my($x,$y) = each(%kv)) { print "$x ",join(",",keys %$y) }}'

281474984889537 112,248
281474985385546 310,20
281475473926267 46,16
我尝试了以下方法:

cat text.txt | perl -F, -lane ' $kv{$F[0]}{$F[1]}++; END { while(my($x,$y) = each(%kv)) { print "$x ",join(",",keys %$y) }}'

281474984889537 112,248
281474985385546 310,20
281475473926267 46,16
在这里,我无法打印第一列值前面的所有值

对于281474984889537,它应该打印68112248249,但它只打印112248

我也不知道如何按升序排列它们

cat text.txt | perl -F, -lane ' $kv{$F[0]}{$F[1]}++; END { while(my($x,$y) = each(%kv)) { print "$x ",join(",",keys %$y) }}'

281474984889537 112,248
281474985385546 310,20
281475473926267 46,16
在这里,我无法打印第1列中值前面的所有值

$ awk -F, '{print $1,$2; print $1,$3}' file             | 
  sort -k1n -k2n                                        | 
  awk 'p!=$1{if(p) print p,a[p]; a[$1]=$2; p=$1; next} 
            {a[$1]=a[$1] "," $2} 
       END  {print p,a[p]}'                             | 
  sort -k2n

281475473926267 16,17,46,47
281474985385546 20,28,310,311
281474984889537 68,112,248,249

使用GNU awk实现真正的多维数组,并按以下方式排序:

$ cat tst.awk
BEGIN { FS="," }
{
    for (i=2; i<=NF; i++) {
        keyVals[$1][$i]
    }
}
END {
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (key in keyVals) {
        vals = ""
        for (val in keyVals[key]) {
            vals = (vals == "" ? "" : vals ",") val
        }
        print key, vals
    }
}

$ awk -f tst.awk file
281474984889537 68,112,248,249
281474985385546 20,28,310,311
281475473926267 16,17,46,47
$cat tst.awk
开始{FS=“,”}
{
对于(i=2;i这可能适用于您(GNU-sed):


该脚本分为两部分。在处理的第一部分,文件的行被保存在内存中,并通过将同一个键的值附加到单个键来减小大小。在文件结束时,执行处理的第二部分。每一行被分成两行,附加的值被排序并重新附加到键上,打印并删除oved,直到处理完所有行。

要更正Perl oneliner,请使用此命令

$ cat text.txt
281475473926267,46,47
281474985385546,310,311
281474984889537,248,249
281475473926267,16,17
281474985385546,20,28
281474984889537,112,68

$ cat text.txt | perl -F, -lanE ' @t1=@{$kv{$F[0]}}; push(@t1,@F[1..2]); $kv{$F[0]}=[@t1]; END { while(my($x,$y) = each(%kv)) { print "$x ",join(",",@{$y}) }}'
281474985385546 310,311,20,28
281475473926267 46,47,16,17
281474984889537 248,249,112,68

$
当您有更多列时,将上述一行从
1..2
更改为
1..$#F
就可以了。请查看此项

$ cat > text2.txt
281475473926267,46,47,49
281474985385546,310,311
281474984889537,248,249,311,677,213
281475473926267,16,17
281474985385546,20,28
281474984889537,112,68,54,78,324,67


$ cat text2.txt | perl -F, -lanE ' @t1=@{$kv{$F[0]}}; push(@t1,@F[1..$#F]); $kv{$F[0]}=[@t1]; END { while(my($x,$y) = each(%kv)) { print "$x ",join(",",@{$y}) }}'
281474984889537 248,249,311,677,213,112,68,54,78,324,67
281474985385546 310,311,20,28
281475473926267 46,47,49,16,17

$

是否始终有3列?是的。始终有3列。可能会有更多列,如281475473926267,46,47,12,13。谢谢。正在努力获取一行中的值,但不帮助我按升序排列。请参阅我的o/p--------------------------------------------------------------------------------------------sort-t,-k2n snclabeltest.txt | awk-F,'{(i=2;iyes,我注意到了同样的问题并更新了脚本。请测试新的一个。awk-F,{print$1,$2;print$1,$3}'snclabeltest.txt | sort-k1n-k2n | awk'p!=$1{if(p)print p,a[p];a[$1]=$2;p=$1;next}{a[$1]=a[$1]=a[$1],“$2}END{print p,a[p]}|排序-k2n 281475473926267 16,17,46,47 281474985385546 20,28310311 281474984889537 68112248,249@JeevanPatil如果同一个键在多个输入行上出现相同的值,那么它将在输出中多次出现。这是您想要的行为吗?在您发布的示例输入中添加一行,如
281475473926267,16,18
,然后看看脚本输出,看看我的意思。是的。我明白你的意思。实际上,对于输入文件,在第2列中不应该有任何重复值,到现在为止,我只是遇到一些垃圾重复值,我忽略了它们。所以到现在为止,上面的命令看起来很完美。