我使用查找目录中的所有文件,所以我得到了一个路径列表。但是,我只需要文件名。例如,我得到。/dir1/dir2/file.txt,我想要得到file.txt
当前回答
使用-execdir自动保存当前文件{},例如:
find . -type f -execdir echo '{}' ';'
您也可以使用$PWD代替。(在某些系统上,它不会在前面产生一个额外的点)。
如果你仍然有一个额外的点,或者你可以运行:
find . -type f -execdir basename '{}' ';'
-execdir utility[参数…]]; -execdir primary与-exec primary相同,不同之处在于实用程序将从包含当前文件的目录执行。
当使用+而不是;时,对于每次实用程序调用,{}将被替换为尽可能多的路径名。换句话说,它将在一行中打印所有文件名。
其他回答
我已经找到了一个解决方案(在makandracards页面),这给了最新的文件名:
ls -1tr * | tail -1
(感谢Arne Hartherz)
我用它来写cp:
cp $(ls -1tr * | tail -1) /tmp/
如果你的find没有-printf选项,你也可以使用basename:
find ./dir1 -type f -exec basename {} \;
如果您只想对文件名运行一些操作,那么使用basename可能会比较困难。
比如这个:
find ~/clang+llvm-3.3/bin/ -type f -exec echo basename {} \;
只会回显basename /my/found/path。如果我们想在文件名上执行,这不是我们想要的。
但是你可以xargs输出。例如,根据另一个目录下的文件名删除一个目录下的文件:
cd dirIwantToRMin;
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \; | xargs rm
-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会发送所有的路径参数(实际上是5000个)而不带-n1。不适用于linux和openbsd,只适用于macOS…)
一些来自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
正如其他人指出的那样,您可以将find和basename结合起来,但是默认情况下basename程序一次只在一个路径上操作,因此可执行文件必须为每个路径启动一次(使用find…-exec或find…| xargs -n 1),可能会很慢。
如果您在basename上使用-a选项,那么它可以在一次调用中接受多个文件名,这意味着您可以使用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实际上要快得多。
推荐文章
- 在Bash中检查变量是否存在于列表中
- 查看PS命令的全部输出
- 确保一次只运行一个shell脚本实例的快速方法
- Linux命令将域名转换为IP
- 如何从命令行在windows中找到mysql数据目录
- 如何在Makefile中设置子进程的环境变量
- 如何让“wc -l”打印没有文件名的行数?
- 有效地测试Linux上的端口是否打开?
- 如何从另一个文件A中删除文件B中出现的行?
- 对以制表符分隔的文件进行排序
- Shell脚本删除超过n天的目录
- 使用sudo时未找到命令
- 当有命令行参数时,如何使用GDB分析程序的核心转储文件?
- 如何检查shell脚本中是否存在命令?
- 如何使用查找命令从列表中查找所有具有扩展名的文件?