xargs 的最终论点
Posted
技术标签:
【中文标题】xargs 的最终论点【英文标题】:Final arguments for xargs 【发布时间】:2013-12-14 16:41:57 【问题描述】:我想做类似的事情:
find . -type f | xargs cp dest_dir
但是xargs
将使用dest_dir
作为初始参数,而不是作为最终参数。我想知道:
-
是否可以为
xargs
指定最终参数?
还有其他方法可以达到同样的效果吗?
编辑
一个可能但麻烦的替代方案是:
find . -type f | while read f ; do echo cp $f dest_dir ; done
我不喜欢这样,因为会启动几十个cp
进程。
【问题讨论】:
【参考方案1】:-I
选项将初始参数中出现的replace-str
替换为从标准输入读取的名称。
例如:
find . -type f | xargs -I file cp file dest_dir
应该可以解决你的问题。
以下教程中的更多详细信息:
http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/
尤其是关于作为参数列表标记的部分
【讨论】:
但是,-I
暗示了-L 1
,这意味着它仍然存在 OP 试图避免的问题(“我不喜欢这样,因为将启动数十个 cp 进程。 ")【参考方案2】:
我试图使用 xargs 和 pdfunite 实现一些稍微不同的东西,但启动多个 pdfunite 实例并没有为我解决问题。
我实际上是在尝试这样做:
$ ls -v *.pdf | xargs pdfunite <files> all-files.pdf
all-files.pdf
是 pdfunite 的最后一个参数。但是xargs
和-I
并没有给我想要的:
$ ls -v *.pdf | xargs -I pdfunite all-files.pdf
这只是给了我一个结果,all-files.pdf
是ls
输出的最后一个文件。那是因为启动了多个 pdfunite 实例。
我最终放弃了xargs
,并采用了以下更简单的构造,这足以满足我的目的:
$ pdfunite `ls -v *.pdf` all-files.pdf
希望这对将来的人有所帮助。
【讨论】:
Backtick/$()
扩展有各种讨厌的副作用。
另外,避免使用ls
进行解析。【参考方案3】:
通常,您不需要使用xargs
(例如find . -type f -exec cp dest_dir +
)。但以防万一……
只需将以下脚本保存在$PATH
中,然后像这样使用它:
find . -type f | xargs final-args dest_dir -- cp
脚本:
#!/bin/bash
# Usage: final-args 4 5 6 -- echo 1 2 3
final=()
for arg
do
shift
if [[ "$arg" = "--" ]]
then
break
fi
final+=("$arg")
done
exec "$@" "$final[@]"
【讨论】:
【参考方案4】:作为替代解决方案,在命令支持时使用-t
。 cp
和 mv
有。
find -type f -print0 | xargs -0 cp -t dest_dir --
find -type f -exec cp -t dest_dir -- +
正如o11c 所指出的,在这种情况下使用xargs
是没有必要的。
另外请注意,我在第一个示例中使用了-print0
和-0
。使用'\0'
作为分隔符可以避免文件名带有换行符的问题。
这里的每个人也不建议至少使用-d '\n'
。 xargs
在未指定时拆分空格(不仅仅是换行符)。
find -type f | xargs -d '\n' cp -t dest_dir --
【讨论】:
这是对 GNUcp
和 mv
的一个很好的建议,但我不认为它是可移植的。例如,BSD 实用程序(至少是我管理的 Mac OS X 机器上的那些)不支持 -t 标志。 (只有 -i
和 -f
标志是 POSIX)。【参考方案5】:
GNU Parallel handles this better than xargs,避免上述变通方法,如果你有的话。
http://www.gnu.org/software/parallel/
【讨论】:
以上是关于xargs 的最终论点的主要内容,如果未能解决你的问题,请参考以下文章