Sort

根據第二個欄位排序,然後重新排序具有相同第一列的行,但仍保持每個組的第二個欄位的順序

  • March 27, 2021

我想對文件進行排序。

輸入:

I1, -2   
I2, -6  
I2, -9  
I1, -8  
I1, -1  
I3, -7  
I2, -4  
I3, -4  

輸出 :

I2, -9  
I2, -6  
I2, -4  
I1, -8  
I1, -2  
I1, -1  
I3, -7  
I3, -4

如何獲得以下輸出?

一個骯髒的解決方案是:

<infile sort -t, -rk2,2 \
|awk -F, '{ seen[$1]= (seen[$1]==""? "\0":seen[$1] ORS) $0 }
END{ for (x in seen) print seen[x] }' \
|sort -z -t, -rk2,2 \
|tr -d '\0'

分解:

  • <infile sort -t, -rk2,2

這樣做reverse*infile*將第二個欄位(逗號是分隔符)上的輸入文件排序為key 欄位。

  • awk程式碼只是對具有相同第一列的記錄重新排序;我們用空字元分隔每個組\0
  • sort -z -t, -rk2,2
    -z這反向對第二個欄位和逗號分隔欄位上的 那些塊(用空字元分隔;我們告訴排序命令)進行排序。請在執行此步驟之前查看以下輸出並添加cat -A您將看到:
^@I1, -8$
I1, -2$
I1, -1$
^@I2, -9$
I2, -6$
I2, -4$
^@I3, -7$
I3, -4$

^@字元代表空字元,sort -z看到上面的輸入是這樣的(我這樣做是為了人類可讀和更好的理解)

^@I1, -8$      I1, -2$      I1, -1$
^@I2, -9$      I2, -6$      I2, -4$
^@I3, -7$      I3, -4$

你明白了,上面的排序命令看到第二個欄位如下

-8$      I1
-9$      I2
-7$      I3

…並對這些進行反向排序,它會更改為以下內容:

^@I2, -9$      I2, -6$      I2, -4$
^@I1, -8$      I1, -2$      I1, -1$
^@I3, -7$      I3, -4$

…如果我們返回結構,我們實際上是這樣的:

^@I2, -9$
I2, -6$
I2, -4$
^@I1, -8$
I1, -2$
I1, -1$
^@I3, -7$
I3, -4$
  • tr -d '\0'

這將從結果中刪除添加的空字元,最終輸出為:

I2, -9
I2, -6
I2, -4
I1, -8
I1, -2
I1, -1
I3, -7
I3, -4

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