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

问题描述 投票:0回答:4

在 Unix 中使用

xargs
应用程序的示例可以是这样的:

ls | xargs echo

这与(假设我在工作目录中有

someFile
someDir/
)相同:

echo someFile someDir

所以

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

但有时我希望

xargs
将其输入放置在下一个命令的中间的某个位置。

例如:

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

有办法吗?

P.S.:在某些情况下我需要它,因为例如:

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`
unix g++ xargs
4个回答
17
投票

回答标题中提出的原始问题,即如何使用

xargs
并在中间而不是末尾输入:

$ echo a b c | xargs -I {} echo before {} after
before a b c after

这会将命令中的

{}
替换为管道输出。 BSD 和 GNU xargs 之间存在一些细微的差异,如下所述:

BSD xargs(例如在 MacOS/Darwin、freebsd 上)

使用

-I REPLACE
,它将替换命令中的字符串
REPLACE
(或您传递的任何内容)。例如:

$ 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 上)

$ echo a b c | xargs -i echo before {} after
before a b c after
$ echo a b c | xargs -I THING echo before THING after
before a b c 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.

-L 1
上的
-I
表示它将在单独的命令中执行每个输入:

$ echo "a
> b
> c" | xargs -I THING echo before THING after
before a after
before b after
before c after

6
投票

如果您的 xargs 版本不包含

-I
功能,另一种方法是编写一个包含您要执行的命令的小 shell 脚本:

#!/bin/sh
exec i586-mingw32msvc-g++ "$@" -o outputFile...

然后使用 xargs 运行它:

find . -type f -name "*.cpp" -print | xargs my_gcc_script

1
投票

您不需要

xargs
为此。只需使用:

g++ `find . -type f -name '*.cpp'` -o outputFile

1
投票

GNU Parallel http://www.gnu.org/software/parallel/ 也是一个解决方案:

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

*.cpp 必须适合单行 (~128 KB)。

© www.soinside.com 2019 - 2024. All rights reserved.