I am trying to get only the names from the search result using find, but it always includes the directories too. How can I print only the names (or assign to a variable) using find

find trunk/messages/ -name "*.po" -printf '%f\n'

a similar command to assign this to a variable e.g. "resource" to use it later on.

EDIT: And if possible only the name excluding the extension.


Use find trunk/messages/ -name "*.po" -exec basename {} .po \;

Example and explanations:

Create some test files:

$ touch test1.po  
$ touch test2.po  
$ find . -name "*.po" -print

Ok, files get found, including path.

For each result execute basename, and strip the .po part of the name

$ find . -name "*.po" -exec basename \{} .po \;  
  • Great thanks :). Can I strip only the PO extension from dirs? I mean: dir1/po1.po and dir2/po2.po can they be got like dir1/po1 and dir2/po2? – wakeup Mar 2 '13 at 14:47
  • @user1754665 find . -name '*.po' -exec bash -c 'echo ${0%.po}' {} \; – slhck Mar 2 '13 at 14:50
  • @slhck thanks. lastly I need to get the filename without extension and the last folder where it is in: e.g: dir1/subdir1/subsubdir1/po1.po and dir2/subdir2/subsubdir2/po2.po should be set to a variable like: subsubdir1/po1 subsubdir2/po2, respectively. – wakeup Mar 2 '13 at 14:58
  • @user1754665 Hmm, maybe find . -name '*.po' -type f -exec sh -c 'echo $(basename $(dirname $0))/$(basename $0)' {} \; – slhck Mar 2 '13 at 15:29
  • @Hennes What is the purpose of backslash before the opening curly brace in the last find? – Utku Oct 31 '17 at 2:10

You can use -execdir parameter which would print the file without path, e.g.:

find . -name "*.po" -execdir echo {} ';'

Files without extensions:

find . -name "*.txt" -execdir basename {} .po ';'

Note: Since it's not POSIX, BSD find will print clean filenames, however using GNU find will print extra ./.

See: Why GNU find -execdir command behave differently than BSD find?


Based on a command I found here: http://www.unixcl.com/2009/08/remove-path-from-find-result-in-bash.html

You could do this using sed (which executed faster for me, than the basename approach):

find trunk/messages/ -name "*.po" | sed 's!.*/!!' | sed 's!.po!!'

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.