我的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
由于
答案 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
函数
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
。我们在这个新数组中对这些元素进行排序,并在最后打印时附加第一个列元素。