for i in *; do echo `echo "$i" | wc -c` "$i"; done | sort -n | cut -f2- -d" " | xargs -d \\n ls -UldLet's break this command into peaces and describe what it does.
The first compound command starting with for and ending with the first pipe character has a task to output length of a name following by a space and then by name itself. You can try to run it within some directory and what you'll get will look similar to this:
1 aWhat we've got is something to sort on (number a.k.a. length) and we keep name as well since we need it for later.
4 name
7 testing
2 ab
The next command in pipeline will sort this output so that the shortest name is first, following the longer ones and finally ending up with the longest name, i.e. we'll get
1 aSince we have now sorted names we don't need length any more and thus we get rid of it using cut command as the next command in the pipeline. The output after cut command will look like this:
2 ab
4 name
7 testing
aNow, if there are no spaces in the names, then it's easy, just hand over this list to the ls command. The command would then look like this:
ab
name
testing
ls -Uld `for i in *; do echo `echo "$i" | wc -c` "$i"; done | sort -n | cut -f2- -d" "`Note backticks before for and at the end of the command line! The options U, l and d cause ls not to sort anything (U), to provide long output (l) and not to list content of directories (d).
But, in case there are spaces in names, this will fail horribly, as many other things do when they encounter spaces in names. So, the trick used in this case was to employ xargs command that collects standard input and runs command with certain number of arguments collected from stdin. The xarg command is
xargs -d \\n ls -UldIn this command with option d we are telling xargs that delimiter between arguments is new line, and not space which is default setting. The rest of the line xargs takes as-is and just adds arguments and runs a command.
And that's it!
By the way, I also unsuccessfully tried to collect arguments into array by reading names with while loop (and read command). The problem is that any variable being set within while command is lost after while finishes and I didn't managed to pass this out of the while loop.
No comments:
Post a Comment