I want to take all files from the current directory and give them to "locate" to check if they are elsewhere. So I started with

find -maxdepth 1 -type f -name "libd*" -exec locate {} ';'

But this does not work because find returns the names in a form like "./libdrm.so" and locate does not work with the leading dot. So I thought locate -b should help:

find -maxdepth 1 -type f -name "libd*" -exec locate -b {} ';'

Unfortunately, locate -b ./libdrm.so does not work, I regard this as a bug. So I tried it with basename:

find -maxdepth 1 -type f -name "libd*" -exec locate \`basename {}\` ';'

This does not work either because `basename {}` is resolved first and the result is "-exec locate '{}' ';'".

Any idea how I can pass "locate `basename {}`" to the exec?


Since you only want to search for files in the actual folder you also could use

locate libd*

or something like as follows, but does not make much sense.

ls libd* | xargs locate
locate $(ls libd*)

If you want to use find, you also could use * instead of ., but I also would quote the {}.

find * -maxdepth 1 -name "libd*" -exec locate "{}" ';'

Lastly, if you want to include dot-files, aka hidden files with glob.

shopt -s dotglob
find * -maxdepth 1 -name "libd*" -exec locate "{}" ';'
shopt -u dotglob
  • I like this ls libd* | xargs locate nice combo! – George Udosen Sep 17 '17 at 17:45
  • why does "find -exec" return all names with a leading "./" whereas "find * -exec" does not? – user372194 Sep 17 '17 at 18:31
  • find without a starting point uses . as default. If you use *, it will expand due to shell glob before the find command starts. So find will search on the expanded glob results. – Thomas Sep 18 '17 at 6:42

I would suggest either

find . -maxdepth 1 -name "libd*" -exec sh -c 'for f; do locate "${f##*/}"; done' sh {} +


find . -maxdepth 1 -name "libd*" -printf '%f\0' | while read -rd '' f; do locate "$f"; done
  • I think the "while read" trick is very useful, thanks. This way one can concatenate many commands. – user372194 Sep 17 '17 at 17:31

This works for me:

find -maxdepth 1 -type f -name "libd*" | sed -r 's/^\.\///' | xargs locate

sed -r 's/^\.\///': removes the ./ from the find command

find -maxdepth 1 -name "libd*" | sed 's^\./^^' | locate -

This solution for sure is not elegant, but it works for me – sed 's^\./^^' simply deletes “./” from the beginning of each line.

If you want to use multiple command in -exec, do it this way:

find -maxdepth 1 -name "libd*" -exec bash -c 'basename $1 | locate -' {} \;
  • Use cut -d/ -f2 it's easier to read. – waltinator Sep 18 '17 at 4:13
  • @waltinator That's a matter of taste, but using a different delimiter is a good idea here – have ^ for fun! :) – dessert Sep 18 '17 at 5:21

Your Answer

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