2017-02-12 49 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 
相关问题