2017-02-12 47 views
1

我有一個包含以下行的文本文件。如何按段落對文件內容進行排序

Number: "472" 
displayname: "jack holi" 

Number: "392" 
displayname: "david" 

Number: "376" 
displayname: "joly" 

Number: "481" 
displayname: "john doe" 

.... 

如何將它們按升序排列按編號排序,並有像下面

Number: "376" 
displayname: "joly" 

Number: "392" 
displayname: "david" 

Number: "472" 
displayname: "jack holi" 

Number: "481" 
displayname: "john doe" 

回答

2

Perl的輸出來救援!

perl -e 'BEGIN { $/ = "" } 
     print for map $_->[1], 
      sort { $a->[0] <=> $b->[0] } 
      map [ /Number: "(\d+)"/, $_ ], 
      <>;' -- input.txt 

BEGIN塊接通段落模式,即文件是由操作者金剛石段讀,即,通過空行分隔的文本塊。

它使用Schwartzian變換,即它將每個塊映射到一對Number, block,然後按數字對這些對進行排序並將它們映射回塊,現在按照正確的順序。

+1

感謝它的魅力 –

3

如果你還在尋找一個(因數組排序GNU)awk的解決方案,你可以使用這個腳本:

script.awk

BEGIN { ORS= RS="\n\n" 
     FS="[\n:]" 
     PROCINFO["sorted_in"] = "@ind_num_asc" 
     } 

     { gsub(/"/, "", $2) 
     so[ $2 + 0 ] = $0 } 

END { for(k in so) print so[k] } 

使用方法如下awk -f script.awk yourfile

說明

  • 記錄分隔RS被設置爲兩個新行,使數量和顯示名稱成爲相同的記錄
  • Fiedld分離FS設置爲newlline的成員或:使我們得到了號碼,顯示名稱及其值作爲字段$1,$3,$2,$4分別爲
  • 將該記錄放入so下的密鑰$2so由(數@ind_num_asc
  • 只在最後一切都印
+1

@EdMorton感謝您的建議。我更新了答案。 –

1

這裏有一個稍微不同的看法......在從GNU輸入文件一次讀取兩條線並行排序和把它們一起在同一行,對它們進行排序,然後再次向上分割線:

parallel -L2 -ra input.txt echo | sort -n | perl -pe 's/" /"\n/; $_.="\n"' 
0

對於早期版本的gawk沒有PROCINFO數組掃描順序,你可以這樣做:

awk 'function cmp(i1, v1, i2, v2) 
        { return (i1-i2) } 
    BEGIN   { ORS=RS="\n\n" } 

        { s=$2 
        gsub(/"/, "", s) 
        arr[s]=$0 } 

    END   { 
        asorti(arr, so, "cmp") 
        for (k in so) 
          print arr[so[k]]}' file 
相關問題