If you are just looking for files in one directory, not in nested directories, you can use a glob argument to your command, which will be interpreted by the shell and produce one argument to your command for each matching filename:
$ echo *.txt
file1.txt file2.txt file3.txt
If you are looking for files nested arbitrarily deeply within subdirectories, find
is indeed what you are looking for. You need to pass in the directory you are looking in, and use the -name
parameter with a quoted glob expression to find the appropriate files (if the glob is not quoted, the shell will try to interpret it, and substitute a list of files matching that name in the current directory, which is not what you want):
$ find . -name "*.txt"
file1.txt. file2.txt file3.txt subdir/file.txt
If you want to pass these in as arguments to another function, you can use $()
(which is equivalent to the more familiar backquotes ``
),
echo $(find . -name "*.txt")
Or if you are going to get a list that is too long for a single argument list, or need to support spaces in your filename, you can use xargs
, which divides its input up into chunks, each of which is small enough to be passed into a command.
find . -name "*.txt" | xargs echo
If your filenames contain whitespace, then xargs
will split them up into two pieces, treating each as a separate argument, which is not what you want. You can avoid this by using the null character, 0
, as the delimiter, with the -print0
argument to find
and the -0
argument to xargs
.
find . -name "*.txt" -print0 | xargs -0 echo