2013-07-09 52 views
0

我有一個CSV文件中像這樣:如何將不同的排序方法應用於BASH中的CSV文件中的不同列?

fish,4 
cat,1 
elephant,1 
tree,2 
dog,8 
car,10 

awk -F',' '{print length($1),$0}' file.csv | sort -k1nr | cut -d' ' -f 2-將字長度的文件進行排序,對於出現在第一列中所有的字:

elephant,1 
fish,4 
tree,2 
cat,1 
dog,8 
car,10 

​​將整理從最大到文件至少根據出現在第二列的數字:

car,10 
dog,8 
fish,4 
tree,2 
elephant,1 
cat,1 

我該如何使用這兩個comman根據出現在第一列中的詞,首先按照詞長度對CSV文件進行排序,然後根據第二列中出現的數量從第一列到第二列中的任何行進行排序最小。生成的輸出如下所示:

elephant,1 
fish,4 
tree,2 
car,10 
dog,8 
cat,1 

這兩種排序方法如何一起使用?

回答

1

如果您使用的是,則可以使用asort函數來執行排序,因此不需要調用其他實用程序。你可以嘗試這樣的事情:

awk -F, 'function cmp(i1,v1,i2,v2) {split(v1,a1); split(v2,a2) 
    l1=length(a1[1]); l2=length(a2[1]) 
    return l1 > l2 ? -1 : l1 < l2 ? 1 : a1[2] > a2[2] ? -1 : a1[2] < a2[2] 
} 
{a[n++]=$0} 
END{asort(a,a,"cmp"); for(i in a) print a[i]}' infile 

輸出:

elephant,1 
fish,4 
tree,2 
car,10 
dog,8 
cat,1 

此腳本讀取所有行第一則叫排序與a功能cmp數組。我使用a > b的唯一技巧是爲truefalse返回通常的1或0。

一點點較短的版本在

perl -F, -ane 'push @a,[@F]; 
    END{for $i(sort {length $b->[0]<=>length $a->[0] or $b->[1]<=>$a->[1]} @a) {printf "%s,%d\n", @$i} 
}' infile 

這不是100%正確的,因爲$F[1]包含\n,但printf妥善處理它。

0

顛倒排序順序,然後用-s進行第二類排序stable

5

嘗試這一行:

awk -F, '{print length($1)","$0}' file|sort -t, -rn -k1 -k3|sed 's/[^,],//' 

會給你:

elephant,1 
fish,4 
tree,2 
car,10 
dog,8 
cat,1 

的想法是,先加COL1輸出的長度,然後進行排序AWK的兩列輸出,最後取出添加長度列(第一列)以獲得最終結果。

相關問題