我正在使用find目录中的所有文件,因此我得到了一个路径列表。但是,我只需要文件名。即我得到./dir1/dir2/file.txt
,我想获得file.txt
答案 0 :(得分:298)
在GNU find
中,您可以使用-printf
参数,例如:
find /dir1 -type f -printf "%f\n"
答案 1 :(得分:139)
如果您的find没有-printf选项,您也可以使用basename:
find ./dir1 -type f -exec basename {} \;
答案 2 :(得分:22)
使用-execdir
自动保存{}
中的当前文件,例如:
find . -type f -execdir echo '{}' ';'
您也可以使用$PWD
代替.
(在某些系统中,它不会在前面产生额外的点)。
如果你还有一个额外的点,或者你可以运行:
find . -type f -execdir basename '{}' ';'
-execdir utility [argument ...] ;
-execdir
主要内容与-exec
主要内容相同,但实用程序将从保存当前文件的目录执行。
使用+
而不是;
时,{}
将替换为每次调用实用程序时尽可能多的路径名。换句话说,它会在一行中打印所有文件名。
答案 3 :(得分:21)
如果您正在使用GNU find
find . -type f -printf "%f\n"
或者您可以使用Ruby(1.9 +)等编程语言
$ ruby -e 'Dir["**/*"].each{|x| puts File.basename(x)}'
如果你想要一个bash(至少4个)解决方案
shopt -s globstar
for file in **; do echo ${file##*/}; done
答案 4 :(得分:11)
如果您只想对文件名运行某些操作,则使用basename
可能会很困难。
例如:
find ~/clang+llvm-3.3/bin/ -type f -exec echo basename {} \;
只会回显基本名称/my/found/path
。如果我们想在文件名上执行,那不是我们想要的。
但是你可以xargs
输出。例如,根据另一个目录中的名称杀死目录中的文件:
cd dirIwantToRMin;
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \; | xargs rm
答案 5 :(得分:5)
在Mac(BSD find
)上使用:
find /dir1 -type f -exec basename {} \;
答案 6 :(得分:2)
正如其他人指出的那样,您可以组合使用find
和basename
,但是默认情况下basename
程序一次只能在一个路径上运行,因此可执行文件必须为每个路径启动一次(使用find ... -exec
或find ... | xargs -n 1
),这可能很慢。
如果您在-a
上使用basename
选项,那么它可以在一次调用中接受多个文件名,这意味着您可以在不使用xargs
的情况下使用-n 1
,以将路径归为更少的basename
调用,这应该更有效率。
示例:
find /dir1 -type f -print0 | xargs -0 basename -a
在这里,我包括了-print0
和-0
(应该一起使用),以便处理文件和目录名称中的任何空格。
这是xargs basename -a
和xargs -n1 basename
版本之间的时间比较。 (为了进行类似比较,此处报告的时序是在初始虚拟运行之后执行的,因此它们都在文件元数据已复制到I / O缓存之后才完成。) cksum
在这两种情况下,只是为了证明输出与所使用的方法无关。
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 basename -a | cksum'
2532163462 546663
real 0m0.063s
user 0m0.058s
sys 0m0.040s
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 -n 1 basename | cksum'
2532163462 546663
real 0m14.504s
user 0m12.474s
sys 0m3.109s
如您所见,避免每次启动basename
确实要快得多。
答案 7 :(得分:1)
-exec
和-execdir
慢,xargs
为王。
$ 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
的并行性也有帮助。
很有趣的是,如果没有xargs
,我无法解释-n1
的最后一种情况。
它给出正确的结果,并且是最快的¯\_(ツ)_/¯
({basename
仅接受1个路径参数,但是xargs
将不带-n1
的所有参数(实际上为5000)发送出去。在linux和openbsd上不起作用,仅macOS ...)< / p>
从Linux系统中获取更多数字,以了解-execdir
有何帮助,但仍然比并行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
答案 8 :(得分:1)
老实说,basename
和dirname
解决方案更容易,但是您也可以查看以下内容:
find . -type f | grep -oP "[^/]*$"
或
find . -type f | rev | cut -d '/' -f1 | rev
或
find . -type f | sed "s/.*\///"
答案 9 :(得分:-3)
我找到了一个解决方案(在makandracards页面上),它只提供了最新的文件名:
ls -1tr * | tail -1
(感谢Arne Hartherz)
我将它用于cp
:
cp $(ls -1tr * | tail -1) /tmp/