1

Say I have a list of keywords:

$ cat filenames.txt 
satin
perdido
savoy
stockings
april
lullabye

I want to find all the files in some directory that contains those keywords.

I have tried something like:

find some_dir/ -type f "$(printf '-or -iname *%s* ' $(cat filenames.txt))"

But somehow I am not able to use printf to build the whole find command; I get:

-bash: printf: -o: invalid option
  • Your question is not clear to me. Do you want to list files that are named satin etc. or that contain the text satin etc.? – PerlDuck Dec 24 '18 at 10:27
  • 2
    Sorry, I realize it was unclear. I want to find all files whose file NAME is a string that contains one of the keywords... – fricadelle Dec 24 '18 at 12:20

1 Answers1

1

The find command does not search the files' content.

The -iname option selects the filenames.

The error means that printf does not reconize the -o option. In such situation you should use printf -- '-o...

I think the final filter you are looking for is:

find some_dir/ -type f \( -iname \*satin\* -o -iname \*perdido\* ... \)

Note the \( ... \) to enclose all the -iname ...

-o ... is said to be POSIX in the man find

You need to be sure that the filenames.txt file contains at least one value.

If you need to find the filenames in the some_dir/, then give a try to this:

set -f ; find some_dir/ -type f \( $(printf -- ' -o -iname *%s*' $(cat filenames.txt)| cut -b4-) \) ; set +f
Jay jargot
  • 526
  • 2
  • 6
  • Your last command is what I am looking for thanks! But adding the keyword "artistry" to filenames.txt should have at least returned to me the file "01 Stan Kenton - Artistry In Rythm.flac" present in one of the subfolders of some_dir. But it didn't... – fricadelle Dec 24 '18 at 12:25
  • @fricadelle: true! , the command had been updated. A possible solution is to deactivate glob to avoid filename expansion with set -f ; find ... ; set +f. – Jay jargot Dec 24 '18 at 13:23
  • 1
    I think I'd use an array - for example mapfile -t filenames < filenames.txt and then find . \( -false $(printf -- ' -o -iname *%s*' "${filenames[@]}") \) (note the -false dummy predicate that allows us to start the list with a -o) – steeldriver Dec 24 '18 at 13:39
  • @steeldriver: super! thx for the info – Jay jargot Dec 24 '18 at 13:42