4

I have an index-of-a-book-like list of lines, say

day
    satur-
    sun-
    holy-
night
    ball
    to-
eve
    election
    christmas

Now I want to sort these lines in the obvious fashion: I want to group every “parent”-entry (day, night, eve) with their respective indented “child”-entries (satur-, sun-, …) and sort these groups by their parent-entry. I also want to sort the child-entries within any given group.

Thus, the desired output is:

day
    holy-
    satur-
    sun-
eve
    christmas
    election
night
    ball
    to-

How would I best achieve this by using unix core tools like sort?

  • 1
    vim can solve the second half of your question with the this: GqqV?^\w<CR>j:sor<CR>kkq. It defines a macro, q, which you can execute with @q to sort each subsection and move up to the previous. Sorting the actual sections I'm still looking into. Does vim count as a core tool? – DopeGhoti May 23 '17 at 22:17
6

You could pick a character that's unlikely to occur in your text file, prepend the parent name + that character to each child line, sort then remove the parent name and the separator from each child line e.g. with gnu sed and a low ascii char like \x02

sed '/^[^[:blank:]]/h;//!G;s/\(.*\)\n\(.*\)/\2\x02\1/' infile | sort | sed 's/.*\x02//'

How it works:
the 1st sed does the following:
/^[^[:blank:]]/h - copy non indented lines (parents) over hold space
//!G - on indented lines (children) append hold space content to pattern space
s/\(.*\)\n\(.*\)/\2\x02\1/ - swap lines in pattern space replacing the \newline with \x02
after that, sort and remove everything up to and including \x02 with a 2nd sed 's/.*\x02//'

  • That’s a good idea, thanks. Can you explain a bit how this first sed line works? – k.stm May 23 '17 at 22:44
  • Yeah, it is! I get it know. It’s a great solution, thank you! – k.stm May 24 '17 at 5:30
  • Worth noting that this isn't recusive - the OP asked for only two levels of sorting so this doesn't help those of us looking for a more general solution. :/ – Joe Dec 10 '18 at 21:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.