0

I have a file with a list of names:

john
paul
ringo
george
...

Then I have a bunch of files with a lot of different names:

maria.iso
jose.iso
pablo.iso
john.iso
jack.iso
jane.iso
...

I want to execute a find command that outputs only the files that have the same name as one of the file list, or none if there's no match. In my example:

john

Something like this:

find . -type f -name "*.iso" (in array)

But I don't know if it's possible or where to start if it is.

So far my only idea is to code a for loop, but that seems ugly and very inefficient.

Thanks

  • what about find . -type f -name '*.iso' | grep -f your_list? – mosvy Sep 6 '19 at 19:34
3

Use readarray to read the names into an array names. Then loop each of the elements in the array to do the find command.

readarray names < names.txt

for n in ${names[@]};do
    find . -type f -name "${n}.iso"
done
3

It would be easier with zsh:

names=(${(f)"$(<name-list.txt)"})

ls -ld -- **/(${(j:|:)~${(b)names}}).iso(D)

Where:

  • $(<file) ksh-style operator that expands to the content of file
  • f parameter expansion flag the splits on linefeeds, so we store in $names the lines of name-list.txt
  • ${(b)var} escapes the glob operators in the content of $var.
  • j:|:: joins the elements of the arrays with with |
  • ~ treat that expansion as a glob pattern.
  • **/: recursive globbing (search in any level of subdirectories).
  • (D): glob qualifier that enables dotglob (include hidden files and search inside hidden dirs like find would do) for that one glob.

So if name-list.txt contains:

foo
bar?

We end up running:

ls -ld -- **/(foo|bar\?).iso(D)

To list the files called wither foo.iso or bar?.iso anywhere under the current directory.

2

You can do "or" tests in find: find . -name a -o -name b ....

So, modifying your file to add the switches, and using xargs to build the find command:

awk 'NR > 1 {print "-o"}; {print "-name", $0".iso"}' input-file | xargs find . 

For a sufficiently small list, this should run only one find. If you have blanks, quotes or other special characters in the filenames, consider using records separated by the ASCII null character (GNU sed can be used to modify the input in that case).

  • 1
    ?, *, [ and backslash would also need to be escaped for find's -name. – Stéphane Chazelas Sep 6 '19 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.