text-processing command-line sort – How to Sort Letters in a Word in a Line of Text

command linesorttext processing

So I have a file full of test commands that I like to run against some of my functions to make sure they are handling all possible situations correctly. No point in having duplicate commands tho. Here's some examples:

rap ,Xflg MIT X11           
rap ,XPBfl 'MITER'
rap ,Bflg share git-grep    
rap ,bfl X11
rap ,Bfl xzfgrep
rap ,Bf X11

… my function 'rap' uses a comma instead of a dash to indicate the start of letter options, then there's some argument following. Since the order of these options doesn't matter:

rap ,Bf X11
rap ,fB X11

… are exactly the same command. Easy to remove duplicate lines from the file of course, however to avoid the above problem, what I'd like to be able to do is to sort the options alphabetically so that the above would end up:

rap ,Bf X11
rap ,Bf X11

… and I'd then be able to delete the duplicates. Can something like that be done without heroics? Note this is not sorting 'by' the list of options, but sorting the options themselves.

Best Answer

Another perl variant:

$ perl -pe 's{^rap ,\K\S+}{join "", sort split //, $&}e' file
rap ,Xfgl MIT X11
rap ,BPXfl 'MITER'
rap ,Bfgl share git-grep
rap ,bfl X11
rap ,Bfl xzfgrep
rap ,Bf X11

For your extra requirement of having lower case letters before upper case ones, you can rely on the fact that in ASCII, 'x' is 'X' ^ 32 (and 'X' is 'x' ^ 32):

$ perl -pe 's{^rap ,\K\S+}{join "", sort {(ord($a)^32) <=> (ord($b)^32)} split //, $&}e' file
rap ,fglX MIT X11
rap ,flBPX 'MITER'
rap ,fglB share git-grep
rap ,bfl X11
rap ,flB xzfgrep
rap ,fB X11
Related Question