Awk

對 CSV 文件的元素進行排序

  • February 27, 2019

我有一個 csv 文件,每行有七個數字,如下所示:

1083,20,28,42,23,10,43
1084,20,5,29,59,40,33
1085,39,50,21,12,40,55
1086,45,4,6,23,10,2
1087,36,46,28,32,3,20

我想保留第一個數字(第 1 列)並對第 2 到第 7 列進行排序,使文件像

1083,10,20,23,28,42,43
1084,5,20,29,33,40,59
1085,12,21,39,40,50,55
1086,2,4,6,10,45,23
1087,3,20,28,32,36,46

我怎樣才能做到這一點awksed或者其他什麼?

謝謝

您面臨的問題是您有帶有 MAC 行結尾 (\r) 的文件,而您正在執行的命令假設 Unix 行結尾 (\n)。

使用Perl

$ perl -l015 -F, -0015 -pae '$_ = join ",", shift @F, sort { $a <=> $b } @F' input.csv

選項:

  • -l設置ORS\r= 八進制 15。
  • -0設置RS\r= 八進制 15。
  • -p將按記錄循環遍歷您的 csv 文件。RS 將記錄從輸入文件中分割出來,\r-0選項設置。
  • -F將在讀取每條記錄時將欄位分隔符設置為逗號。
  • -a將分割每條記錄,因為它被讀入欄位並儲存在數組中@F
  • 注意:提供選項的順序很重要。

因此,您將獲得的輸出也應具有 MAC 行結尾。這就是為什麼您沒有看到預期的輸出,而是根據此處給出的所有解決方案,您的所有輸出記錄都被壓縮成一行。

perl

perl -F, -lape '$_ = join ",", shift @F, sort {$a <=> $b} @F' < input.csv

使用 GNU awk

gawk -F, '
 {
   split($0, a)
   printf "%s", a[1]
   delete a[1]
   n = asort(a)
   for (i = 1; i <= n ; i++) printf "%s", FS a[i]
   print ""
 }' < input.csv

或者使用join.awk圖書館(感謝@WeijunZhou)

gawk -i join -F, -v OFS=, '
 {
   split($0, a)
   first = a[1]
   delete a[1]
   n = asort(a)
   print first, join(a, 1, n, OFS)
 }'

引用自:https://unix.stackexchange.com/questions/503096