As suggested by derobert, your best bet is to use find
. However, you can in fact use the result in a pipeline with other commands.
GNU (and some BSD's) find
support the -print0
predicate which tells it to print the filename terminated by a NUL character, which character isn't allowed within a file name and guarantees there won't be a collision. Other commands can be instructed to use the NUL as their input delimiter.
The most important of which is GNU xargs
, which runs the command you specify and passes to it the list of files as command line arguments. You want to run xargs -r0
in conjunction with find's -print0
For example:
find . -type f ! \( -name \*.pdf -o -name \*.txt \) -print0 | xargs -r0 ls -ld
This safely prints a long directory listing of all the pdf and txt files, including those with spaces or unprintable characters in the name.
You can also use it with GNU tar
as follows:
tar -zcf myarchive.tar.gz --null --files-from <(
find . -type f ! -name \*.tar.gz -print0)
This builds a tar.gz file of all the files whose names don't end in .tar.gz
rsync
also accepts null-delimited files with the -0
parameter, as do several others. But xargs
is the glue you'll usually use for this type of purpose. Either that or find
's -exec
feature.
ls
vsfind
vs globbing may differ for hidden dotfiles.find
will traverse subdirectories, like a recursivels
. Use-maxdepth 1
withfind
to get it to behave more likels
.