对行组

时间:2018-02-22 10:42:04

标签: bash shell awk sed grep

说我有这个清单:

sharpest
  tool
  in
the
  shed
im
  not
  the

如何通过非缩进行按字母顺序排序并保留行组?以上应该成为:

im
  not
  the
sharpest
  tool
  in
the
  shed

类似的问题存在herehere,但我似乎无法让它们适合我的榜样。

到目前为止充满希望的想法

  • 也许我可以用某种方式使用grep -n,因为它给了我行号?我想先得到行号,然后订购。我猜我在某种程度上需要在订购之前计算一个行范围,然后从那里以某种方式获取行的范围。但是,甚至不能想到如何做到这一点!
  • 范围也看起来很有希望,但同样的交易; sed 1,2pfurther examples here

4 个答案:

答案 0 :(得分:3)

如果perl没问题:

$ perl -0777 -ne 'print sort split /\n\K(?=\S)/' ip.txt
im
  not
  the
sharpest
  tool
  in
the
  shed
  • -0777啜饮整个文件,因此输入太大时解决方案不合适
  • split /\n\K(?=\S)/使用换行符后跟非空白字符作为拆分指示
  • sort对数组进行排序

答案 1 :(得分:3)

您可以在一个asort命令中使用此gnu awk函数:

awk '{if (/^[^[:blank:]]/) {k=$1; keys[++i]=k} else arr[k] = arr[k] $0 RS} 
END{n=asort(keys); for (i=1; i<=n; i++) printf "%s\n%s", keys[i], arr[keys[i]]}' file

im
  not
  the
sharpest
  tool
  in
the
  shed

Code Demo

使用awk + sort的替代解决方案:

awk 'FNR==NR{if (/^[^[:blank:]]/) k=$1; else arr[k] = arr[k] $0 RS; next}
{printf "%s\n%s", $1, arr[$1]}' file <(grep '^[^[:blank:]]' file | sort)

im
  not
  the
sharpest
  tool
  in
the
  shed

编辑:POSIX合规性:

#!/bin/sh
awk 'FNR==NR{if (/^[^[:blank:]]/) k=$1; else arr[k] = arr[k] $0 RS; next} {printf "%s\n%s", $1, arr[$1]}' file | 
  grep '^[![:blank:]]' file | 
  sort

答案 2 :(得分:1)

使用单个GNU awk 命令:

awk 'BEGIN{ PROCINFO["sorted_in"] = "@ind_str_asc" }
     /^[^[:space:]]+/{ k = $1; a[k]; next }
     { a[k] = (a[k]? a[k] ORS : "")$0 }
     END{ for(i in a) print i ORS a[i] }' file

输出:

im
  not
  the
sharpest
  tool
  in
the
  shed

答案 3 :(得分:0)

awk单行

$ awk '/^\w/{k=$1; a[k]=k; next} {a[k]=a[k] RS $0} END{ n=asorti(a,b); for(i=1; i<=n; i++) print a[b[i]] }' file
im
  not
  the
sharpest
  tool
  in
the
  shed