我试图找到子目录中分布的某种类型的所有文件,而就我的目的而言,我只需要文件名。我尝试通过 删除路径组件basename
,但它对 不起作用xargs
:
$ find . -name '*.deb' -print | xargs basename
basename: extra operand `./pool/main/a/aalib/libaa1_1.4p5-37+b1_i386.deb'
Try `basename --help' for more information.
使用以下任何一种变化,我都会得到同样的事情(完全相同的错误):
$ find . -name '*.deb' -print0 | xargs -0 basename
$ find . -name '*.deb' -print | xargs basename {}
另一方面,这可以按预期工作:
$ find . -name '*.deb' -exec basename {} \;
foo
bar
baz
这发生在最新的 Cygwin 和 Debian 5.0.3 上。我的诊断是 xargs 出于某种原因将两行输入传递给 basename,但为什么呢?这是怎么回事?
答案1
因为basename
只需要一个参数... 而不是很多。并xargs
创建了很多参数。
为了解决您的实际问题(仅列出文件名):
find . -name '*.deb' -printf "%f\n"
仅打印“basename”(man find):
%f File's name with any leading directories
removed (only the last element).
答案2
尝试这个:
find . -name '*.deb' | xargs -n1 basename
答案3
basename 只接受一个参数。使用-exec
可以正常工作,因为每个{}
参数都被当前正在处理的文件名替换,并且命令只运行一次每个匹配的文件,而不是尝试一次性将所有参数发送给 basename。
答案4
原因是默认情况下xargs
不会仅使用一个输入项来构建一个命令调用。
事实上,xargs
每次执行命令时,都会使用尽可能多的输入项,其中构建一次命令调用所使用的最大项数是系统定义的值,可以通过-n
或-L
选项覆盖。例如,如果您运行echo a b | xargs ls
,而不是分别使用和执行ls
两次,则会构建并运行单个命令。a
b
xargs
ls a b
因此,对于仅接受一个参数的命令(如),如果您想坚持使用,则basename
应该使用-n
或选项。-L
xargs