【问题标题】:to arrange the value in columns as per value in 1st column根据第一列中的值排列列中的值
【发布时间】:2019-06-06 17:53:36
【问题描述】:

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

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

第一列的值在某些地方重复 我想要下面给出的o/p

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

这里我无法打印第一列值前面的所有值

对于 281474984889537,它应该打印 68,112,248,249,但它只打印 112,248

我也不确定如何按升序排列它们。

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

这里我无法打印第一列值前面的所有值

【问题讨论】:

  • 总是有 3 列吗?
  • 是的。总是 3 列
  • 可能会有更多的列,例如 281475473926267,46,47,12,13

标签: perl unix awk sed solaris


【解决方案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

【讨论】:

  • 谢谢。努力将值排成一行,但不帮助我按升序排列。请看我的o/p-------------------------------------------------------- -------------------排序 -t, -k2n snclabeltest.txt | awk -F, '{for(i=2;i
  • 是的,我注意到了同样的问题并更新了脚本。请测试新的。
  • awk -F, '{打印 $1,$2;打印 $1,$3}' snclabeltest.txt |排序-k1n -k2n | awk 'p!=$1{if(p) print p,a[p]; a[$1]=$2; p=$1;下一个} {a[$1]=a[$1] ","$2} END {打印 p,a[p]}' |排序-k2n 281475473926267 16,17,46,47 281474985385546 20,28,310,311 281474984889537 68,112,248,249
  • @JeevanPatil 如果相同的值出现在多个输入行的同一个键上,那么它将在输出中出现多次。这是你想要的行为吗?将281475473926267,16,18 之类的行添加到您发布的示例输入中,然后查看脚本输出以了解我的意思。
  • 是的..我明白你的意思。实际上对于输入文件,第二列中不应该有任何重复值,到目前为止,我只是遇到了一些垃圾重复值并且我忽略了它们。所以到目前为止上面的命令看起来很完美。
【解决方案2】:

使用 GNU awk 实现真正的多维数组和 sorted_in:

$ 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

无论您在每行有多少个字段,上述方法都将起作用,并且当重复值出现在同一键值的多行上时,它将删除重复值。

【讨论】:

    【解决方案3】:

    这可能对你有用(GNU sed):

    sed -r 'H;x;s/((\n[^\n,]*),[^\n]*)(.*)\2([^\n]*)\n?/\1\4\3/;x;$!d;x;s/.//;:b;h;s/\n.*//;s/[^,]*,//;s/,/\n/g;s/.*/echo "&"|sort -n|paste -sd,/e;G;s/^([^\n]*)\n([^\n,]*),[^\n]*/\2 \1/;P;:c;tc;s/[^\n]*\n//;tb;d' file
    

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

    【讨论】:

      【解决方案4】:

      要更正您的 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
      
      $
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-08
        • 2022-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-02
        相关资源
        最近更新 更多