对csv文件中的行进行排序,不带标题&第一栏

时间:2018-02-22 06:02:16

标签: awk sed

我的CSV文件包含如下记录。

   id,h1,h2,h3,h4,h5,h6,h7 
   101,zebra,1,papa,4,dog,3,apple
   102,2,yahoo,5,kangaroo,7,ape

我想在没有标题和第一列的情况下将行排序到此文件中。我的输出应该是这样的。

  id,h1,h2,h3,h4,h5,h6,h7
  101,1,3,4,apple,dog,papa,zebra
  102,2,5,7,ape,kangaroo,yahoo

我在AWK下面尝试过,但不知道如何排除标题和第一列。

awk -F"," ' {
s=""
for(i=1; i<=NF; i++) { a[i]=$i; }
for(i=1; i<=NF; i++)
{
for(j = i+1; j<=NF; j++)
{
if (a[i] >= a[j])
{
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
for(i=1; i<=NF; i++){ s = s","a[i]; }
print s
} 
' file

由于

3 个答案:

答案 0 :(得分:5)

如果perl没问题:

$ perl -F, -lane 'print join ",", $.==1 ? @F : ($F[0], sort @F[1..$#F])' ip.txt
id,h1,h2,h3,h4,h5,h6,h7 
101,1,3,4,apple,dog,papa,zebra
102,2,5,7,ape,kangaroo,yahoo
  • -F,表示,为字段分隔符,结果保存在@F数组中
  • join ","使用,作为输出字段分隔符
  • 第一行
  • $.==1 ? @F,按原样打印
  • ($F[0], sort @F[1..$#F])对于其他行,获取其他字段的第一个字段和已排序的输出
    • ..是范围运算符,$#F将给出最后一个字段的索引


对于给定的标题,排序第一行也会起作用,因此这可以简化所需的逻辑

$ perl -F, -lane 'print join ",", $F[0], sort @F[1..$#F]' ip.txt
id,h1,h2,h3,h4,h5,h6,h7 
101,1,3,4,apple,dog,papa,zebra
102,2,5,7,ape,kangaroo,yahoo

$ ruby -F, -lane 'print [$F[0], $F.drop(1).sort] * ","' ip.txt
id,h1,h2,h3,h4,h5,h6,h7 
101,1,3,4,apple,dog,papa,zebra
102,2,5,7,ape,kangaroo,yahoo

答案 1 :(得分:4)

如果您gawk使用asort

awk -v OFS="," 'NR>1{split($0, a, ",");
                $1=a[1];
                delete a[1];
                n = asort(a, b);
                for (i = 1; i <= n; i++){ $(i+1)=b[i]}};
                1' file.csv

这将列分割为数组a,分隔符为,,除了第一个原始数据之外的所有原始数据。

然后使用a中的第一个值分配raw中列中的第一个值,并从a中删除此值。

现在a已排序为b,并从2列开始分配值。然后打印出来。

答案 2 :(得分:2)

您可以使用asort()中的awk功能满足您的要求,并开始从第二行开始对它们进行排序。由于awk函数

,解决方案是GNU length(array)特定的
awk 'NR==1{ print; next }
     NR>1 { finalStr="" 
            arrayLength=""
            delete b
            split( $0, a, "," )
            for( i = 2; i <= length(a); i++ )
                b[arrayLength++] = a[i]
            asort( b )
            for( i = 1; i <= arrayLength ; i++ ) 
                finalStr = (finalStr)?(finalStr","b[i]):(b[i])
            printf( "%s", a[1]","finalStr )
            printf( "\n" ); 
    }' file

我们的想法是首先将整个行与,分隔符分成数组a,然后我们从第2个字段开始将元素转换为新的数组b。我们在这个新数组中对这些元素进行排序,并在最后打印时附加第一个列元素。