Yves Yves - 1 year ago 40
Linux Question

How to make order for strings according to some filed

<scene name="scene_1_Overview" title="1 Overview" onstart="" thumburl="panos/1_Overview.tiles/thumb.jpg" lat="" lng="" heading="">
abc
</scene>

<scene name="scene_1_Overview" title="10 Overview" onstart="" thumburl="panos/1_Overview.tiles/thumb.jpg" lat="" lng="" heading="">
abc
</scene>

<scene name="scene_10_Room_Balcony_View" title="2 Room Balcony View" onstart="" thumburl="panos/10_Room_Balcony_View.tiles/thumb.jpg" lat="" lng="" heading="">

abc
def
</scene>


Saying that I have such a XML file as above.

Now I need to make the three elements in order according to the numbers followed by
title=
, which are 1, 10 and 2.


I'm considering using bash script to do this.

I can use things like
awk '{print $3}' test | awk -F "\"" '{print $2}'
to get the three numbers but I don't know how to read multiple lines from each
<scene
to
</scene>
, to make them in order and overwrite them.

Answer Source

I think doing this in awk is not the greatest idea, but I know what it's like being stuck on a box where you lack access to install anything. If you are stuck with it then something like the following awk script should get you in the ballpark.

 awk -F"[\" ]" '$0~/title/{title=$6} {scene[title]=scene[title]$0"\n"} END{PROCINFO["sorted_in"]="@ind_num_asc"; for (title in scene) {print scene[title]}}' inFile

Here awk is:

  1. Splitting each line by either " or (-F"[\" ]")
  2. If the line contains the word "title" ($0~/title/), then it sets the variable title to whatever it finds in field 6 (title=$6;) which might change if your "name" contains spaces since we are splitting on that so you might have to monkey with the delimiters.
  3. Next it stores the contents of the line, followed by a linefeed, into the array scenes at the index set by the number stored in title ({scene[title]=scene[title]$0"\n"})
  4. Once it's done processing the file it sets the PROCINFO["sorted_in"] setting to @ind_num_asc which tells awk to loop through arrays using the index, while forcing the index to act as a number (END{PROCINFO["sorted_in"]="@ind_num_asc")
  5. Then we loop through the array and print each element (for (title in scene) {print scene[title]})

Minimized a bit:

 awk -F"[\" ]" '$0~/title/{t=$6}{s[t]=s[t]$0"\n"}END{PROCINFO["sorted_in"]="@ind_num_asc";for(t in s)print s[t]}' inFile
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download