In general, it's often needed to find a file whose name should contain several substrings simultaneously. How do I do that with bash?

For example, "boost", "qt" and "linux" in a file called "How to link boost with qt under linux.htm"

P.S Finally, I've managed to find the file using:

find . -name *boost* | xargs find . -name *Qt*

but first it gives out this complaint:

xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
find: paths must precede expression

So, I'm still looking for some clearer solution.

P.S The solution of Stéphane Chazelas has helped. The issue was with big letter 'b' in "boost", so I should've made this find case-insensitive:

find . -iname '*boost*' -iname '*qt*'
find /some/path -name '*boost*' -name '*Qt*'

Or to match on the full path:

find /some/path -path '*boost*' -path '*Qt*'

If you don't quote those patterns, they'll be expanded by your shell first.

For case insensitive match, some find implementations have -iname/-ipath. Otherwise, you can always do:

find /some/path -name '*[bB][oO][oO][sS][tT]*' -name '*[qQ][tT]*'

Or, assuming file paths don't contain newline characters:

find /some/path |
  awk -F/ '{lname=tolower($NF)}; lname ~ /boost/ && lname ~ /qt/'
  • I've tried the both - they didn't give any output on my machine. – alxprogger Jun 9 '15 at 12:13
  • Sorry. It helped. The issue was boost was with 'b' letter: it was "Boost". – alxprogger Jun 9 '15 at 12:19
  • So how to make "find" it case-insensitive in my case? – alxprogger Jun 9 '15 at 12:20

Use find /some/path -name "*boost*" -a -name "*qt*" etc.

The -a means "and" to find.

  • I've already tried that. It didn't work for me. But the file exists. – alxprogger Jun 9 '15 at 10:30
  • Did it give an error? Did it not find the file(s)? – Jeff Schaller Jun 9 '15 at 11:01
  • No, it didn't give an error message. I've updated the question, look P.S. – alxprogger Jun 9 '15 at 11:03
  • 1
    @alxprogger this will work, at least on GNU find. Note that you need to quote the strings as in the updated answer": "*boost*", not *boost*. Your updated question doesn't show what happens when you try this. – terdon Jun 9 '15 at 11:19
  • Thanks, @terdon, for the edit and comment. @alxprogger, you don't need two find commands and the xargs (in your updated question) -- just the one find. – Jeff Schaller Jun 9 '15 at 11:23

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.