Sorting the output of "find -print0" by piping to the "sort" command
Solution 1
Use find
as usual and delimit your lines with NUL. GNU sort
can handle these with the -z switch:
find . -print0 | sort -z | xargs -r0 yourcommand
Solution 2
Some versions of sort
have a -z
option, which allows for null-terminated records.
find folder1 folder2 -name "*.txt" -print0 | sort -z | xargs -r0 myCommand
Additionally, you could also write a high-level script to do it:
find folder1 folder2 -name "*.txt" -print0 | python -c 'import sys; sys.stdout.write("\0".join(sorted(sys.stdin.read().split("\0"))))' | xargs -r0 myCommand
Add the -r
option to xargs
to make sure that myCommand
is called with an argument.
Solution 3
I think you need the -n
flag for sort#
According to man sort:
-n, --numeric-sort
compare according to string numerical value
edit
The print0 may have something to do with this, I just tested this. Take the print0 out, you can null terminate the string in sort using the -z
flag
Solution 4
If you have GNU Parallel http://www.gnu.org/software/parallel/ installed you can do this:
find folder1 folder2 -name "*.txt" -print |
sort |
parallel myCommand
You can install GNU Parallel simply by:
wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
Watch the intro videos for GNU Parallel to learn more: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Solution 5
Some implementation of find
supports ordered traversal directly via the -s
parameter:
$ find -s . -name '*.json'
From the FreeBSD find man page:
-s Cause find to traverse the file hierarchies in lexicographical
order, i.e., alphabetical order within each directory. Note:
`find -s' and `find | sort' may give different results.
Industrial
I just want to lie on the beach and eat hot dogs. That’s all I’ve ever wanted. Really.
Updated on September 18, 2022Comments
-
Industrial almost 2 years
I need to be able to alphabetically sort the output of
find
before piping it to a command. Entering| sort |
between didn't work, so what could I do?find folder1 folder2 -name "*.txt" -print0 | xargs -0 myCommand
-
Industrial over 12 yearsWell, that
print0
appears to be space-separating the filenames which is what I need to pass to my command, unfortunately -
Peter.O over 12 yearsGood one (two?)... Interestingly, though, the two methods handle
.
differently... Withsort
it winds up at the end of the list... withpython
it sorts to the top. (maybe python sorts withLC_COLLATE=C
) -
Peter Mortensen almost 10 yearsWhat is the justification for using GNU Parallel? To speed it up?
-
Ole Tange almost 10 yearsThat and you do not need to mess with \0 separated records.
-
Javier almost 9 yearsThere is also the
-t \0
option for sort (which is a-z
synonym) -
syntaxerror over 8 yearsThe problem with all these
|sort
solutions is that you cannot use-exec
any longer. OK, although it is possible to rewrite your statement given to-exec
so that it works withxargs
, the question is, what about "mini-scripts"? (sh -c ...
) I wouldn't call that trivial to transform a 'sh -c' mini-script with multiple commands so that it can work withxargs
(if possible at all, that is) -
Roger Pate almost 8 years@syntaxerror: What problem do you have using sh -c with xargs?
printf %s\\n a b c d e | xargs -n3 sh -c 'printf %s, "$@"; printf \\n' x
-
uav about 4 yearsI don't understand that last statement. I create a file with a line break in the file name and execute your command:
cd /tmp && touch $'a\nz' && ls && find -maxdepth 1 -print | sort | parallel echo
. Total false output. I know GNU Parallel now, but that answer misses the original question, doesn't it? -
uav about 4 yearsI know that it is bad practice to use crazy characters in file names - I am already including the blank space. I just see that parallel has a -0 parameter. Nice. No downvote.
find -maxdepth 1 -print0 | sort -z | parallel -0 echo
. -
Ole Tange about 4 years@uav In my 25 years of sysadmin I have never seen a user making a file with \n. I have seen plenty of files with ' space and ". So unless you have evil users or a filesystem with error, I will reckon you will not meet a file with \n that was not made by a fellow sysadm.
-
bomben over 3 yearsIt does not seem to work with
find . -name '*.dat' -type f -printf '%f\n' | sort -z | xargs -r0 > output.txt
. Is my line wrong due to the printf? -
ychaouche about 3 years@Ben you're not using -print0 and are introducing newlines instead of NULLs.
-
BMWW almost 3 yearsor together with formating the output
find . -printf "%y %p \n\0" | sort -z