Unix-“Unix”;xargs";-“产出”;“在中间”;(不是在最后!)

Unix-“Unix”;xargs";-“产出”;“在中间”;(不是在最后!),unix,g++,xargs,Unix,G++,Xargs,在Unix中使用xargs应用程序的示例如下: ls | xargs echo g++ a.cpp b.cpp c.cpp -o outputFile 这与(假设我在工作目录中有someFile和someDir/)相同: 因此xargs获取其输入并将其放置在下一个命令的末尾(这里是echo的末尾) 但有时我希望 XARGS 将其输入放在下一个命令的中间。 例如: find . -type f -name "*.cpp" -print | xargs g++ -o outputFile $

在Unix中使用
xargs
应用程序的示例如下:

ls | xargs echo
g++ a.cpp b.cpp c.cpp -o outputFile
这与(假设我在工作目录中有
someFile
someDir/
)相同:

因此
xargs
获取其输入并将其放置在下一个命令的末尾(这里是echo的末尾)

<>但有时我希望<代码> XARGS 将其输入放在下一个命令的中间。

例如:

find . -type f -name "*.cpp" -print | xargs g++ -o outputFile
$ echo a b c | xargs -I {} echo before {} after
before a b c after
$ echo a b c | xargs -I REPLACE echo before REPLACE after
before a b c after
$ echo 'a
> b
> c' | xargs -L1 -I {} echo before {} after
before a after
before b after
before c after
因此,如果我在当前目录中有文件
a.cpp
b.cpp
c.cpp
,输出将与命令相同:

g++ -o outputFile a.cpp b.cpp c.cpp
$ echo "a
> b
> c" | xargs -I THING echo before THING after
before a after
before b after
before c after
但我想要这样的东西:

ls | xargs echo
g++ a.cpp b.cpp c.cpp -o outputFile
有办法吗

附言:在某些情况下我需要它,因为例如:

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
GNU并行也是一种解决方案:

find . -type f -name "*.cpp" -print | parallel -X g++ {} -o outputFile

回答在标题中如何使用<代码> xARGs<代码>的问题,中间输入而不是结尾:

$ echo a b c | xargs -I {} echo before {} after
before a b c after
这将使用管道输出替换命令中的
{}
。BSD和GNU XARG之间有一些细微的区别,如下所述:

BSD xargs(例如,在MacOS/Darwin、freebsd上) 使用
-I REPLACE
,它将替换命令中的字符串
REPLACE
(或您传递的任何内容)。例如:

find . -type f -name "*.cpp" -print | xargs g++ -o outputFile
$ echo a b c | xargs -I {} echo before {} after
before a b c after
$ echo a b c | xargs -I REPLACE echo before REPLACE after
before a b c 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.
GNU xargs(例如在Linux上) 使用
-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
上的
-L 1
表示它将在单独的命令中执行每个输入:

g++ -o outputFile a.cpp b.cpp c.cpp
$ echo "a
> b
> c" | xargs -I THING echo before THING after
before a after
before b after
before c after

-i
没有这种效果,尽管它显然已被弃用。)

我会说在backtick上使用$(),但它很有效,所以我不能抱怨。我使用backtick是因为他没有说他在使用什么shell,backtick可以使用更多shell(例如tcsh)。你真的不应该这样做。空格将打破这一点。这在场景中也不起作用(这是
xargs
的特点之一!),当您的参数超过单个命令行所能容纳的数量时(
getconf ARG_MAX
表示单个进程所允许的所有环境变量和命令行参数的总组合大小)。诚然,
g++
在这种情况下无论哪种方式都会有不当行为,但问答条目的使用超出了第一个提问者的范围。