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

人气:902 发布:2022-10-16 标签: unix g++ xargs

问题描述

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

example use of xargs application in Unix can be something like this:

ls | xargs echo

这与(假设我在工作目录中有 someFilesomeDir/ 相同):

which is the same as (let's say I have someFile and someDir/ in the working directory):

echo someFile someDir

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

so xargs take its input and place it at the end of the next command (here at the end of echo).

但有时我希望 xargs 将其输入放置在下一个命令的中间位置.

But sometimes I want xargs to place its input somewhere in the middle of next command.

例如:

find . -type f -name "*.cpp" -print | xargs g++ -o outputFile

所以如果我在当前目录中有文件 a.cpp, b.cpp, c.cpp 输出将是相同的和命令一样:

so if I had in the current directory files a.cpp, b.cpp, c.cpp the output would be the same as with the command:

g++ -o outputFile a.cpp b.cpp c.cpp

但我想要这样的东西:

g++ a.cpp b.cpp c.cpp -o outputFile

有办法吗?

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

P.S.: I need it in some cases, because e.g.:

i586-mingw32msvc-g++ -o outputFile `pkg-config --cflags --libs gtkmm-2.4` a.cpp b.cpp c.cpp

不起作用,但这个工作正常:

doesn't work but this one works fine:

i586-mingw32msvc-g++ a.cpp b.cpp c.cpp -o outputFile `pkg-config --cflags --libs gtkmm-2.4`

推荐答案

回答标题中关于如何使用xargs的原问题,输入在中间而不是结尾:

To answer the original question asked in the title of how to use xargs with the input in the middle rather than the end:

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

这会将命令中的 {} 替换为管道输出.BSD 和 GNU xargs 之间存在一些细微差别,如下所述:

This replaces {} in the command with the piped output. There are some subtle differences between BSD and GNU xargs described below:

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

Use -I REPLACE, which will replace the string REPLACE (or whatever you pass) in the command. For example:

$ 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 参数,手册页 描述:

Use either the -I REPLACE or the the -i argument, which the man page describes:

   -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 表示它将在单独的命令中执行每个输入:

The -L 1 on -I means that it will execute each of the input in a separate command:

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

(-i 没有这种效果,但显然已被弃用.)

(-i does not have this effect, though is apparently deprecated.)

858