26

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.

3 Answers 3

35

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
./test1.po  
./test2.po

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 \;  
test1  
test2
8
  • 1
    @user1754665 find . -name '*.po' -exec bash -c 'echo ${0%.po}' {} \;
    – slhck
    Mar 2, 2013 at 14:50
  • 1
    @user1754665 Hmm, maybe find . -name '*.po' -type f -exec sh -c 'echo $(basename $(dirname $0))/$(basename $0)' {} \;
    – slhck
    Mar 2, 2013 at 15:29
  • 1
    @Hennes What is the purpose of backslash before the opening curly brace in the last find?
    – Utku
    Oct 31, 2017 at 2:10
  • 1
    The last example contains a stray backslash. Nov 28, 2020 at 4:42
  • 1
    @wakeup you get what you want by combining @slhck's 2 comments because he forgot to strip the extension in the second one. but you can also use the built in function into basename for removing suffixes like find trunk/messages/ -name "*.po" -exec sh -c 'echo "$(basename $(dirname $0))/$(basename -s ".po" $0)"' "{}" \;. Apr 15, 2022 at 17:31
14

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?

2
  • This is the real answer. I need to do some work in "exec" already, so running basename doesn't fly.
    – Ethan
    Sep 19, 2020 at 18:47
  • The command will not print extra ./ in bash if ; character is escaped by \ . Example: '\;'
    – DigiBat
    Jun 29, 2022 at 10:00
2

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!!'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .