I\'m using find to all files in directory, so I get a list of paths. However, I need only file names. i.e. I get ./dir1/dir2/file.txt
and I want to get fi
If you are using GNU find
find . -type f -printf "%f\n"
Or you can use a programming language such as Ruby(1.9+)
$ ruby -e 'Dir["**/*"].each{|x| puts File.basename(x)}'
If you fancy a bash (at least 4) solution
shopt -s globstar
for file in **; do echo ${file##*/}; done
On mac (BSD find
) use:
find /dir1 -type f -exec basename {} \;
If your find doesn't have a -printf option you can also use basename:
find ./dir1 -type f -exec basename {} \;
I've found a solution (on makandracards page), that gives just the newest file name:
ls -1tr * | tail -1
(thanks goes to Arne Hartherz)
I used it for cp
:
cp $(ls -1tr * | tail -1) /tmp/
In GNU find
you can use -printf
parameter for that, e.g.:
find /dir1 -type f -printf "%f\n"
-exec
and -execdir
are slow, xargs
is king.
$ alias f='time find /Applications -name "*.app" -type d -maxdepth 5'; \
f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l; \
f -print0 | xargs -0 basename | wc -l
139
0m01.17s real 0m00.20s user 0m00.93s system
139
0m01.16s real 0m00.20s user 0m00.92s system
139
0m01.05s real 0m00.17s user 0m00.85s system
139
0m00.93s real 0m00.17s user 0m00.85s system
139
0m00.88s real 0m00.12s user 0m00.75s system
xargs
's parallelism also helps.
Funnily enough i cannot explain the last case of xargs
without -n1
.
It gives the correct result and it's the fastest ¯\_(ツ)_/¯
(basename
takes only 1 path argument but xargs
will send them all (actually 5000) without -n1
. does not work on linux and openbsd, only macOS...)
Some bigger numbers from a linux system to see how -execdir
helps, but still much slower than a parallel xargs
:
$ alias f='time find /usr/ -maxdepth 5 -type d'
$ f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l
2358
3.63s real 0.10s user 0.41s system
2358
1.53s real 0.05s user 0.31s system
2358
1.30s real 0.03s user 0.21s system
2358
0.41s real 0.03s user 0.25s system