0

I have a text config file which is like this:


config server 'server'
        option url 'https://chef.libremesh.org'

config client 'client'
        option upgrade_packages '1'
        option auto_search '0'
        option advanced_mode '0'

I want the output to be like this:


config client 'client'
        option advanced_mode '0'
        option auto_search '0'
        option upgrade_packages '1'

config server 'server'
        option url 'https://chef.libremesh.org'

Which command to use ?

1 Answer 1

1

My perl is a bit rusty, so this can certainly be made cleaner. Try:

perl -nE 'BEGIN{$/=""}; @b = split "\n", $_; 
    @a = shift @b; push @a, sort @b; 
    push @f, join("\n", @a); END{ say "$_\n" foreach sort @f }' input

Set $/ to the empty string so that perl reads each section as a record. The initial split splits each record on the newlines, and then we construct the array @a by shifting off the first line of the section and then sorting the remaining lines. Construct a string from that and push it onto the array @f. At the end, sort the sections and write output.

You can trim a bit by autosplitting:

perl -F'\n' -a -nE 'BEGIN{$/=""}; 
    push @f, join "\n", shift @F, sort @F;
    END{ say "$_\n" foreach sort @f } ' input

or:

perl -00 -F'\n' -a -nE 'push @f, join "\n", shift @F, sort @F} 
    {print join "\n\n", sort @f' input

The last command is a somewhat weird idiom which takes advantage of the fact that -n puts the command inside an implicit while(<>){...} construct and the first } in the code matches the implicit { while the "unmatched" { matches the implicit }, making it similar to running the final code in an END block.

Sign up to request clarification or add additional context in comments.

3 Comments

This works great. But it removes the empty lines at the beginning, ending and between the sections. Is it possible to do it without removing the empty lines ?
Ah, yes, those are important. Will fix.
I think you can get what you need by just doing say "$_\n" to add an extra newline after each record.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.