Reputation: 274562
I would like to sort the characters in a string.
E.g.
echo cba | sort-command
abc
Is there a command that will allow me to do this or will I have to write an awk
script to iterate over the string and sort it?
Upvotes: 30
Views: 23346
Reputation: 109
Here is @ghostdog74's answer implemented in fish shell:
string match --all --regex . "cba" | sort | string join ""
Upvotes: 0
Reputation: 21
This would have been more appropriate as a comment to one of the grep -o .
solutions (my reputation's not quite up to that low bar alas, damn my lurking), but I thought it worth mentioning that separating letters can be done more efficiently within the shell. It's always worth avoiding code, but this letsep function is pretty small:
letsep ()
{
INWORD="$1"
while [ "$INWORD" ]
do
echo ${INWORD:0:1}
INWORD=${INWORD#?}
done
}
. . . and outputs one letter per line for an input string of arbitrary length. For example, once letsep is defined, populating an array FLETRS with the letters of a string contained in variable FRED could be done (assuming contemporary bash) as:
readarray -t FLETRS < <(letsep $FRED)
. . . which for word-size strings runs about twice as fast as the equivalent :
readarray -t FLETRS < <(echo $FRED | grep -o .)
Whether this is worth setting up depends on the application. I've only measured this crudely, but the slower procedural code seems to maintain an advantage over the context switch up to ~60 chars (grep is obviously more efficient, but loading it is relatively expensive). If the above operation is taking place in one or more steps of a loop over an indeterminate number of executions, the difference in efficiency can add up (at which point some might argue for switching tools and rewriting regardless, but that's another set of tradeoffs).
Upvotes: 0
Reputation: 166359
Please find the following useful methods:
Shell
Sort string based on its characters:
echo cba | grep -o . | sort | tr -d "\n"
String separated by spaces:
echo 'dd aa cc bb' | tr " " "\n" | sort | tr "\n" " "
Perl
print (join "", sort split //,$_)
Ruby
ruby -e 'puts "dd aa cc bb".split(/\s+/).sort'
Bash
With bash you have to enumerate each character from a string, in general something like:
str="dd aa cc bb";
for (( i = 0; i < ${#str[@]}; i++ )); do echo "${str[$i]}"; done
For sorting array, please check: How to sort an array in bash?
Upvotes: 16
Reputation: 23667
Another perl
one-liner
$ echo cba | perl -F -lane 'print sort @F'
abc
$ # for reverse order
$ echo xyz | perl -F -lane 'print reverse sort @F'
zyx
$ # or
$ echo xyz | perl -F -lane 'print sort {$b cmp $a} @F'
zyx
-l
option
@F
array@F
is printed
This will also work line wise for given input file
$ cat ip.txt
idea
cold
spare
umbrella
$ perl -F -lane 'print sort @F' ip.txt
adei
cdlo
aeprs
abellmru
Upvotes: 6
Reputation: 223003
This is cheating (because it uses Perl), but works. :-P
echo cba | perl -pe 'chomp; $_ = join "", sort split //'
Upvotes: 7