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

发布于 2024-08-04 11:47:03 字数 946 浏览 4 评论 0原文

在 Unix 中使用 xargs 应用程序的示例可以是这样的:

ls | xargs echo

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

echo someFile someDir

因此 xargs 获取其输入并将其放置在下一个命令的末尾(此处位于 echo 的末尾)。

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

例如:

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

所以如果我在当前目录中有文件 a.cppb.cppc.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`

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

ls | xargs echo

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

echo someFile someDir

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

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

For example:

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

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

but I want to have something like this:

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

Is there a way to do it?

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`

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

网白 2024-08-11 11:47:03

回答标题中提出的原始问题,即如何使用位于中间而不是末尾的输入的 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 -I 上的 1 表示它将在单独的命令中执行每个输入:

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

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

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

BSD xargs (e.g. on MacOS/Darwin, freebsd)

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

The man page describes the option:

 -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 (e.g. on 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

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.

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
物价感观 2024-08-11 11:47:03

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

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

然后使用 xargs 运行该脚本:

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

If your version of xargs doesn't include the -I feature, an alternative is to write a little shell script containing the command you want to execute:

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

Then use xargs to run that:

find . -type f -name "*.cpp" -print | xargs my_gcc_script
雨后彩虹 2024-08-11 11:47:03

为此,您不需要 xargs。只需使用:

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

You do not need xargs for this. Just use:

g++ `find . -type f -name '*.cpp'` -o outputFile
半边脸i 2024-08-11 11:47:03

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

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

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

GNU Parallel http://www.gnu.org/software/parallel/ would be a solution too:

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

The *.cpp must fit in a single line (~128 KB).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文