在Unix中使用xargs
应用程序的例子可以是这样的:
ls | xargs echo
这是相同的(假设我有someFile
和someDir/
在工作目录中):
echo someFile someDir
所以xargs
接受它的input并把它放在下一个命令的末尾(这里是echo的结尾)。
但有时候我想让xargs
把它的input放在下一个命令的中间 。
例如:
find . -type f -name "*.cpp" -print | xargs g++ -o outputFile
所以如果我在当前目录下有文件a.cpp
, b.cpp
, c.cpp
,输出将与命令相同:
g++ -o outputFile a.cpp b.cpp c.cpp
但我想要这样的东西:
g++ a.cpp b.cpp c.cpp -o outputFile
有没有办法做到这一点?
PS:在某些情况下我需要它,因为例如:
i586-mingw32msvc-g++ -o outputFile `pkg-config --cflags --libs gtkmm-2.4` a.cpp b.cpp c.cpp
不起作用,但这个工作正常:
i586-mingw32msvc-g++ a.cpp b.cpp c.cpp -o outputFile `pkg-config --cflags --libs gtkmm-2.4`
如果您的xargs版本不包含-I
功能,另一种方法是编写一个包含要执行的命令的shell脚本:
#!/bin/sh exec i586-mingw32msvc-g++ "$@" -o outputFile...
然后使用xargs来运行:
find . -type f -name "*.cpp" -print | xargs my_gcc_script
你不需要这个xargs
。 只要使用:
g++ `find . -type f -name '*.cpp'` -o outputFile
要回答如何在中间而不是结尾使用xargs
的标题中提出的原始问题:
$ echo abc | xargs -I {} echo before {} after before abc after
这将用管道输出替换命令中的{}
。 BSD和GNU xargs之间有一些细微的差别,如下所述:
使用-I REPLACE
,它将替换命令中的字符串REPLACE
(或任何你传递的)。 例如:
$ echo abc | xargs -I {} echo before {} after before abc after $ echo abc | xargs -I REPLACE echo before REPLACE after before abc after $ echo 'a > b > c' | xargs -L1 -I {} echo before {} after before a after before b after before c after
手册页描述了这个选项:
-I replstr Execute utility for each input line, replacing one or more occur- rences of replstr in up to replacements (or 5 if no -R flag is specified) arguments to utility with the entire line of input. The resulting arguments, after replacement is done, will not be allowed to grow beyond replsize (or 255 if no -S flag is speci- fied) bytes; this is implemented by concatenating as much of the argument containing replstr as possible, to the constructed argu- ments to utility, up to replsize bytes. The size limit does not apply to arguments to utility which do not contain replstr, and furthermore, no replacement will be done on utility itself. Implies -x.
$ echo abc | xargs -i echo before {} after before abc after $ echo abc | xargs -I THING echo before THING after before abc after
使用-I REPLACE
或手册页描述的-i
参数:
-I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1. -i[replace-str], --replace[=replace-str] This option is a synonym for -Ireplace-str if replace-str is specified. If the replace-str argument is missing, the effect is the same as -I{}. This option is deprecated; use -I instead.
-I
表示-I
表示它将在一个单独的命令中执行每个输入:
$ echo "a > b > c" | xargs -I THING echo before THING after before a after before b after before c after
( -i
没有这个效果,虽然显然不赞成。)
GNU Parallel http://www.gnu.org/software/parallel/也是一个解决方案:
find . -type f -name "*.cpp" -print | parallel -X g++ {} -o outputFile