If you want to find the files whose name are any of the ones stored in filelist.txt
one per line, one easy way is to use zsh
's globbing
:
names=( ${(f)"$(<filelist.txt)"} ) &&
(( $#names )) &&
print -rC1 -- /home/abc/**/${(~j[|])names}(D.)
As to why your approach doesn't work, it's not immediately obvious, though there are few problems with it:
- In
bash
, that unquoted $(cat filelist.txt)
invokes split+glob (split only in zsh) on the contents of filelist.txt
. With the default value of $IFS
(which is used for the split part), that will split on newline characters but also on space and tab. So if you have a my file.txt
line in there, it will look for files called my
and files called file.txt
instead of files called my file.txt
- If there is a file called
*
in filelist.txt
, the glob part will expand it to the list of files in the directory the script is being called from.
- Also
-name '*'
will not look for a file called *
, but will report every file as what's passed to -name
is taken as a pattern. You'd need to escape the [
, ?
, *
and \
with \
to disable the wildcard operators.
Now, your problem may also be that:
filelist.txt
is in MSDOS text format with CRLF delimiters instead of LF. You'd run dos2unix
on it to fix it.
- that you have file paths in
filelist.txt
(such as dir/file.txt
). -name
matches on the file name only, so would never match on that.
Here, instead of a loop, you could use GNU xargs
:
xargs -rd'\n' -a filelist.txt -I NAME find /home/abc/ -name NAME -type f
But that still means crawling the whole of /home/abc/
for each file name, which is inefficient.
Instead, you could do:
xargs -rd'\n' -n200 -a <(sed 's/[*?\\[]/\\&/g' filelist.txt) sh -c '
for name do
set -- -o -name "$name"
shift
done
shift
find /home/abc/ \( "$@" \) -type f' sh
Where we call find /home/abc/ \( -name name1 -o -name name2... \) -type f
with up to 200 names in one find
invocation, which means potentially 200 as few crawlings of /home/abc
. Not as good as zsh
which does only 1 in any case, but still a lot better.
We also use sed
to escape the wildcard characters in the names. You could also through in a dos2unix
in there.
{}
button to mark it up as code. What happened when you ran it? How did that differ from what you expected? Did you get any errors?filelist.txt
. (Change parts of the values if you must but make sure the shape of the data is exactly the same as your actual data, as otherwise we will answer for the wrong issue.)