Text-Processing

如何按 2 個列名對數據流進行排序(列號可能會有所不同)?

  • January 13, 2016

我從 API 獲取數據流,如下所示:

redID  blueID  whiteID  
1      22       2  
44     15       41  
2      15       15  
31     2       14 

我需要做的是,先對它進行排序blueID,然後whiteID再發送到其他地方。但我事先不知道會有多少列。我所知道的是,總會有至少那兩列。

所以所需的輸出如下所示:

redID  blueID  whiteID  
31     2       14  
2      15      15  
44     15      41  
1      22      2 

有沒有辦法,也許在awk,根據列名對這個流進行排序?

我正在尋找的唯一答案是以下形式:

inputStream | some operations | sortedInputStream

有任何想法嗎?

感謝來自評論和其他來源的想法,我終於能夠編寫這段程式碼並回答我自己的問題:

  inputStream | awk -F'\t' -v OFS="\t" '{
           if ( col1 == ""){
               for (i=1;i<=NF;i++){
                   if ($i == "BlueId"){
                       col1=i;
                   }
                   else if ($i == "WhiteId"){
                       col2=i;
                   }
               }
           print "-1" "\t" "-1" "\t" $0
           }
           else {
               print $col1 "\t" $col2 "\t" $0
           }
       }' | sort -k1,1n -k2,2n | cut -f3- | outputStream

它的工作原理是這樣的:它獲取流數據,找到所需列的編號並在每一行前面列印需要排序的兩個值。然後它對第 1 列和第 2 列進行排序並刪除它們。謝謝!

您可以執行以下操作:

# get the header line from the file and split each header to a different line
header=$(head -1 $file_name | tr ' ' '\n')
# get the index/line number of the blueID
blueID_index=$(echo "$header" | grep -n "blueID" | sed 's/:.*//')
# same for whiteID
whiteID_index=$(echo "$header" | grep -n "whiteID" | sed 's/:.*//')
# now build the sort command with the indexes you just computed
sort -k$blueID_index -k$whileID_index

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