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?
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?
echo cba | grep -o . | sort |tr -d "\n"
grep -o . is a cheap way to each character on its own line before using sortgrep -o '\S'.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?
for (( i = 0; i < ${#str}; i++ )); do echo "${str:${i}:1}" ; done Problem with the original suggestion is that str="dd aa cc bb" does NOT create an array, just a string of characters, and the suggested for loop doesn't step through that string. If the goal is to take in a string and output its contents one character at a time, my amended for loop accomplishes this by extracting each character as a 1-char substring and echoing it.This is cheating (because it uses Perl), but works. :-P
echo cba | perl -pe 'chomp; $_ = join "", sort split //'
echo cba | ruby -e 'puts ARGF.read.split(%r{\s*}).sort.join'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
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).
Here is @ghostdog74's answer implemented in fish shell:
string match --all --regex . "cba" | sort | string join ""