Sort Row Groups

Let's say I have this list:

sharpest tool in the shed im not the 

How can I alphabetize using non-bent strings and save groups of strings? The above should be:

 im not the sharpest tool in the shed 

Similar questions exist here and here , but I cannot get them to work for my example.

Robust ideas so far

  • Maybe I could use grep -n somehow, since it gives me line numbers? I thought to get line numbers first and then order. I think I would need to calculate the range of lines before ordering, and then select a range of lines from there. I can’t even think how to do it, however!
  • ranges look promising, but the same deal; sed 1,2p and further examples here .
+5
source share
4 answers

If perl is ok:

 $ perl -0777 -ne 'print sort split /\n\K(?=\S)/' ip.txt im not the sharpest tool in the shed 
  • -0777 slurp the whole file, so the solution is not suitable if the input is too large
  • split /\n\K(?=\S)/ shows an array using a newline character followed by a character with no spaces as a split indicator
  • sort to sort the array
+3
source

You can use this asort function in one gnu awk command:

 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 

Demo code


Alternative solution using 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 

Edit: POSIX compliance:

 #!/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 
+3
source

With one GNU awk command:

 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 

Output:

 im not the sharpest tool in the shed 
+1
source

awk single line

 $ 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 
0
source

Source: https://habr.com/ru/post/1275511/


All Articles