Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm looking to get a list of just file names (without the rest of the path) when executing the find command from a terminal. How do I accomplish this on the mac?

share|improve this question

7 Answers 7

up vote 9 down vote accepted

With basename:

find . -type f -exec basename {} \;

share|improve this answer
    
What are curly braces for? –  iccthedral Jul 17 '13 at 12:51
    
basename is run once for every found file, denoted by {}. –  Ярослав Рахматуллин Jul 17 '13 at 14:02

Evilsoup mentioned that what was posted doesn't work for spaced file names. So instead you could use:

find . -type f -print0 | while IFS= read -r -d '' filename; do echo ${filename##*/}; done
share|improve this answer
    
This will break on files with spaces in their names (see parsing ls on greg's wiki) –  evilsoup Jul 16 '13 at 22:08
    
@evilsoup - Fixed - thanks for the link! –  nerdwaller Jul 16 '13 at 22:56
    
+1 for speed. I don't know if I did something wrong, but this one took 1 second on my $HOME, whereas all others took around 10 seconds. Of course, I would need more than 10 seconds to look this up and type it. –  Paulo Almeida Jul 16 '13 at 23:19

There is a better way to strip everything but the last portion of a file path; with awk. It is better because awk is not executed once for every file. In some cases this matters.

find ~/tmp/ -type f  | awk -F/ '{ print $NF }'

We look only for files in ~/tmp and we get a list where every entry is separated by slashes. Hence, we use a slash as the field separator (-F/) and print the field parameter ($1..$9) that corresponds to the last field ($NF).

share|improve this answer
    
This is the fastest I tested. –  Paulo Almeida Jul 17 '13 at 14:25
    
I've been using Cygwin lately, and creating a process in windows is super expensive... –  Ярослав Рахматуллин Jul 17 '13 at 14:30

EDIT:

Using sed:

$ find . -type f | sed 's/.*\///'

Using the xargs command, as mentioned in the response of @nerdwaller

$ find . -type f -print0 | xargs --null -n1 basename
share|improve this answer
1  
Thanks for pointing that one out, +1, I haven't used xargs much... Definitely should since you dropped quite a few characters off my command. –  nerdwaller Jul 16 '13 at 20:49
    
This one breaks when files have spaces. It works like this, at least in a quick test: find . -type f -print0| xargs --null -n1 basename –  Paulo Almeida Jul 17 '13 at 14:28
    
@PauloAlmeida: Thanks =] –  QMechanic73 Jul 17 '13 at 16:25

What about this:

find … | egrep -o -e '[^/]+$'

Advantage: Only exactly one additional process is spawned, not one for each result.

share|improve this answer

With GNU find, you can do:

 find ~/tmp/ -printf "%f\n"

This is probably worth trying in OS X too.

share|improve this answer
2  
-printf isn't supported on OS X's BSD find. –  Daniel Beck Jul 16 '13 at 21:22
1  
Also, -printf bears little relation to the C printf or the POSIX shell utility printf. Using this historic function name for something different is very poorly considered. The conservative BSD guys likely see it the same way, so we won't probably won't see clone of -printf in the BSD find, under that name. –  Kaz Jul 17 '13 at 0:42
    
I disagree that it's poorly considered to use a familiar function name to perform a similar task in a different context. Why BSD will probably never support it is another matter. –  Ярослав Рахматуллин Jul 17 '13 at 14:02

You can call sh from within find's -exec option and avoid using uneccesary pipes. This also has the advantage that you don't need to worry about funny filenames (spaces, newlines, etc.):

find . -type f -exec sh -c 'echo "${0##*/}"' {} \;
share|improve this answer

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.