Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I was doing a

find . -iname '*sitesearch*' | grep demo

because I know the file should be some/path/SiteSearch/demo/SiteSearch.html, but it turned out a person put the file in as some/path/SiteSearch/demo/index.html, so the file cannot be found.

Is there a better way to do the search?

Such as for this case, if I do

find . -iname '*demo*' | grep -i sitesearch

it would have found it. But I don't want to always THINK what possibility it is and figure out what pattern to use. I just want a way that whenever the file and path have both of these 2 keywords, then print it out. For example, if there is a way to ls all files will the full path on each line, then we can do

ls --some-flags | grep -i demo | grep -i sitesearch

or maybe another way / better way.

share|improve this question
add comment

1 Answer

You can combine two patterns (or more generally multiple criteria) in find.

find . -ipath '*sitesearch*' -ipath '*demo*'

or if you prefer regex syntax

find . -iregex '.*sitesearch.*' -iregex '.*demo.*'

ls with the full path on each line” (plus traversing directories recursively, which is evidently needed here) would be find. While you can run find | grep -i demo | grep -i sitesearch, doing it all with find is likely to be visibly faster.

If you do this a lot, you can make it a function (put it in your ~/.kshrc or ~/.bashrc or ~/.zshrc):

findallof () {
  typeset -a pred
  pred=(.)
  typeset x
  for x do
    pred=("${pred[@]}" -ipath "*$x*")
  done
  find "${pred[@]}"
}

Note also that you can search for files by name with locate (check the man page on your system as there are several implementations even on Linux).

locate -i sitesearch | grep -i demo

This can be faster than looking through a large directory tree, because locate queries an index (though case-insensitive searches tend not to be that fast). However, the index is typically rebuilt only every night, so it won't show files created today. Files that are not in a publicly readable directory may or may not be indexed depending on the implementation (check if /usr/bin/locate is a setuid root binary: if it is, private files are indexed and the locate command shows you only the files you can access).

share|improve this answer
    
Needs -ipath instead of -iname or it won't find some/path/SiteSearch/demo/index.html like grep would. Also a missing * after demo. –  frostschutz Apr 6 '13 at 0:33
    
later on, I found that find . | grep -i demo | grep -i sitesearch should do the job too. But your solution is just one command so it should be nicer. Do you know how to make it into functions so that we can just say find1 sitesearch or find2 demo sitesearch or if better we don't need to say find1 or find2 but just findallof –  動靜能量 Apr 6 '13 at 2:10
    
@動靜能量 You can make it a function (see my edit). –  Gilles Apr 6 '13 at 12:01
    
this function doesn't work on a Mac... do you have a version that might work on both the Mac and Linux? –  動靜能量 Apr 7 '13 at 7:01
    
@動靜能量 With . after find? GNU find doesn't need it, but I think BSD find does. –  Gilles Apr 7 '13 at 13:51
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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