Unix Scripting : Sort a Portion of a File and not the complete file

Need to sort a portion of a file in a Alphabetical Order.
Example : The user adam is not sorted and the user should get sorted. I don't want the complete file to get sorted.

Currently All_users.txt contains the following lines.

##############
# ARS USERS
##############
mike, Mike Conway, Stevn Smiley, REQ000001, ARS (11)
paul, Paul Smith, Stevn Smiley, REQ000001, ARS (11)
sam, Sam Martin, Stevn Smiley, REQ000001, ARS (11)
adam, Adam smils, Paul Reily, REQ000001, ARS (11)
#
##############
# ATRIUM USERS
##############
randy, Randy Roch, Steven Seagul, REQ000002, ATRIUM (11)
michelle, Michelle Morques, Steven Seagul, REQ000003, ATRIUM (11)
lois, Lois Hill, Randy Rocker, Steven Seagul, REQ000004, ATRIUM (11)
#
##############
# INSTALLER USERS
##############
nguyen, Nguyen Le, Steven Seagul, REQ000001, INSTALLER (13)
mark, Mark Goodwan, Steven Seagul, REQ000005, INSTALLER (13)

I need the output to be sorted like this.

##############
 # ARS USERS
 ##############
adam, Adam smils, Paul Reily, REQ000001, ARS (11)
 mike, Mike Conway, Stevn Smiley, REQ000001, ARS (11)
 paul, Paul Smith, Stevn Smiley, REQ000001, ARS (11)
 sam, Sam Martin, Stevn Smiley, REQ000001, ARS (11)
 #
 ##############
 # ATRIUM USERS
 ##############
 randy, Randy Roch, Steven Seagul, REQ000002, ATRIUM (11)
 michelle, Michelle Morques, Steven Seagul, REQ000003, ATRIUM (11)
 lois, Lois Hill, Randy Rocker, Steven Seagul, REQ000004, ATRIUM (11)
 #
 ##############
 # INSTALLER USERS
 ##############
 nguyen, Nguyen Le, Steven Seagul, REQ000001, INSTALLER (13)
 mark, Mark Goodwan, Steven Seagul, REQ000005, INSTALLER (13)

 

Thanks in advance

sort <filename>
Your issue looks simple.
Is it something you are looking for?

It's not so simple, because he doesn't want to sort the comments along with everything else... I was thinking of splitting the file into n parts for separate sorting based on comments or blanks, but was hoping there was a more straightforward way which eluded me.

@bobbygsk, thanks for your reply.

No, its not that simple as we look like. Sorting the file completely re-orders all the lines.
I need to sort only the portion of the file and not the complete file. My file has 3500 lines and i need to sort only specific lines.

Sort <filename> doesnt provide the result as expected.

root@bmcpunscm-lnx-test: /tmp-> sort < users_all.txt > users_all.txt1
root@bmcpunscm-lnx-test: /tmp-> cat users_all.txt1
#
#
##############
##############
##############
##############
##############
##############
adam, Adam smils, Paul Reily, REQ000001, ARS (11)
# ARS USERS
# ATRIUM USERS
# INSTALLER USERS
lois, Lois Hill, Randy Rocker, Steven Seagul, REQ000004, ATRIUM (11)
mark, Mark Goodwan, Steven Seagul, REQ000005, INSTALLER (13)
michelle, Michelle Morques, Steven Seagul, REQ000003, ATRIUM (11)
mike, Mike Conway, Stevn Smiley, REQ000001, ARS (11)
nguyen, Nguyen Le, Steven Seagul, REQ000001, INSTALLER (13)
paul, Paul Smith, Stevn Smiley, REQ000001, ARS (11)
randy, Randy Roch, Steven Seagul, REQ000002, ATRIUM (11)
sam, Sam Martin, Stevn Smiley, REQ000001, ARS (11)

This should work:

awk ' BEGIN     { sorting=0 }
/^#/    { if (sorting) {
                close("sort")
                sorting=0
          }     
          print 
          next  
        }
        { print | "sort"
          sorting=1
        }
END     { if (sorting) close("sort") }' users_all.txt
1 Like

Thanks a tonnnn Don and your script works Great.
Can you please explain the flow of the script so that i can understand the flow.

The command

print | "sort"

opens up a pipe to a sort command (if a sort command isn't already running) and writes the current input line to it.

The command

close("sort")

closes the pipe and flushes the output from the sort command to standard output.
This is done whenever a pipe to sort is open and either a line starting with "#" is found or the end of the input is found.

So, any line starting with "#" is written directly to standard output by the awk script and any set of lines between lines starting with "#" are piped through sort before being written to standard output.

1 Like