How to I use bash to alphabetize entries in a config file, preserving sequential numbering?

2

0

I have an .ini file with this pattern:

[Preset0]
Data=78367571EE5E
Data_1=3483290482
Data_2=299230-293
Data_3=2390920391
Name=Mono Lead
Len=3994
[Preset1]
Data=78367571EE5E
Data_1=3483290482
Data_2=299230-293
Data_3=2390920391
Name=Funky Bass
Len=4001
[Preset2]
Data=0200002E3434
Data_1=342EFD340433
Data_2=000000043425
Data_3=EDFE00000000
Name=Airy Pad
Len=3713

Each set of data from [PresetX] to Len=X represents one preset. I want to alphabetize this list by Name=X. However, I need the first preset in the file to be [Preset0] and I need the presets to remain in numeric order. So, my desired output would be:

[Preset0]
Data=0200002E3434
Data_1=342EFD340433
Data_2=000000043425
Data_3=EDFE00000000
Name=Airy Pad
Len=3713
[Preset1]
Data=78367571EE5E
Data_1=3483290482
Data_2=299230-293
Data_3=2390920391
Name=Funky Bass
Len=4001
[Preset2]
Data=78367571EE5E
Data_1=3483290482
Data_2=299230-293
Data_3=2390920391
Name=Mono Lead
Len=3994

How would I do this with bash?

3x5

Posted 2017-11-01T20:16:14.887

Reputation: 121

2Your example data does not demonstrate that you have a problem. Are the presets already in numeric order? If they are, how can you sort by Name? – glenn jackman – 2017-11-01T20:38:42.730

Sorry, the presets are already in numeric order. The names are not in alphabetical order. So I need each preset (Data, Data_1, Data_2, Data_3, Name, Len) to go in alphabetical order, without rearranging the preset numbers. – 3x5 – 2017-11-02T00:25:57.007

1Still don't understand. Show more than one complete section and your desired output – glenn jackman – 2017-11-02T00:28:49.107

I didn't understand too. If the Preset numeric order doesn't match the Name alphabetical order, then you must choose one. It seems that the file is already in numeric order of Preset. Do you want to move the entire Preset block to put the blocks in alphabetical order of Name? – Paulo – 2017-11-02T01:39:42.623

Yes Paulo, I want to sort the whole blocks. I have edited my OP to be more clear. – 3x5 – 2017-11-02T11:34:50.200

Answers

1

I don't know how to sort and increment with sed, so this solution mixes sed, bash and sort.

sed -r ':a;N;s/\n/|/;/Len=/{s/(.*Name=)(.*)(Len=.*)/\2\1\3/p;d};ba' presets-file |
sort |
while read line; do
    sed -r 's/(.*\|)(\[Preset)[0-9]+(\].*)(Len=.*)/\2'$((i++))'\3\1\4/;s/\|/\n/g' <<<"$line"
done

Paulo

Posted 2017-11-01T20:16:14.887

Reputation: 606

I'm glad that helped. I forgot to add that if one of the lines contain a | it won't work, because all new lines \n of a block are replaced by | in the first sed, and in the second sed the \n are put back. In this case you should replace it by another 'not occurring' character. – Paulo – 2017-11-08T20:19:16.923