簡體   English   中英

如何在BASH的CSV文件中的不同列上應用不同的排序方法?

[英]How to apply different sorting methods to different columns in a CSV file in 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- 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

sort -t, -k+2 -n -r file.csv將根據第二列中出現的數字sort -t, -k+2 -n -r file.csv對文件進行排序:

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

如何將這兩個命令一起使用,以便首先根據出現在第一列中的單詞按單詞長度對CSV文件進行排序,然后根據出現在其中的數字對包含相同長度單詞的任何行進行排序第二列從最大到最小。 結果輸出如下所示:

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

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

試試這一行:

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的輸出進行排序,最后刪除添加的length列(第一列)以獲得最終結果。

如果您使用的是則可以使用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

該腳本首先讀取所有行,然后使用cmp函數對稱為a的數組進行排序。 我使用的唯一技巧a > btruefalse返回通常的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可以正確處理它。

顛倒排序順序,然后使用-s使第二個排序穩定

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM