让 xargs 对每行输入执行一次命令

发布于 2024-07-06 19:45:32 字数 475 浏览 4 评论 0原文

如何使 xargs 对给定的每一行输入精确执行一次命令? 它的默认行为是对行进行分块并执行一次命令,将多行传递给每个实例。

来自http://en.wikipedia.org/wiki/Xargs

查找 /path -type f -print0 | xargs -0 rm

在此示例中,find 向 xargs 的输入提供一长串文件名。 然后 xargs 将此列表拆分为子列表,并为每个子列表调用 rm 一次。 这比功能等效的版本更有效:

查找 /path -type f -exec rm '{}' \;

我知道 find 有“exec”标志。 我只是引用另一个资源中的一个说明性示例。

How can I make xargs execute the command exactly once for each line of input given?
It's default behavior is to chunk the lines and execute the command once, passing multiple lines to each instance.

From http://en.wikipedia.org/wiki/Xargs:

find /path -type f -print0 | xargs -0 rm

In this example, find feeds the input of xargs with a long list of file names. xargs then splits this list into sublists and calls rm once for every sublist. This is more efficient than this functionally equivalent version:

find /path -type f -exec rm '{}' \;

I know that find has the "exec" flag. I am just quoting an illustrative example from another resource.

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

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

发布评论

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

评论(13

黯然#的苍凉 2024-07-13 19:45:32

仅当您的输入中没有空格时,以下内容才有效:

xargs -L 1
xargs --max-lines=1 # synonym for the -L option

从手册页:

-L max-lines
          Use at most max-lines nonblank input lines per command line.
          Trailing blanks cause an input line to be logically continued  on
          the next input line.  Implies -x.

The following will only work if you do not have spaces in your input:

xargs -L 1
xargs --max-lines=1 # synonym for the -L option

from the man page:

-L max-lines
          Use at most max-lines nonblank input lines per command line.
          Trailing blanks cause an input line to be logically continued  on
          the next input line.  Implies -x.
北恋 2024-07-13 19:45:32

在我看来,这一页上所有现有的答案都是错误的,包括标记为正确的答案。 这是因为这个问题的措辞含糊不清。

摘要: 如果您想执行命令“每行输入只执行一次”,将整行(不带换行符)作为单个参数传递给命令,那么这是最好的 UNIX 兼容方法:

... | tr '\n' '\0' | xargs -0 -n1 ...

如果您使用 GNU xargs 并且不需要与所有其他 UNIX(FreeBSD、Mac OS X 等)兼容,那么您可以使用GNU 特定选项 -d

... | xargs -d\\n -n1 ...

现在进行详细解释……


使用 xargs 时需要考虑两个问题:

  1. 它如何将输入拆分为“参数”; 以及
  2. 一次传递子命令的参数数量。

为了测试 xargs 的行为,我们需要一个实用程序来显示它被执行了多少次以及有多少个参数。 我不知道是否有一个标准实用程序可以做到这一点,但我们可以很容易地在 bash 中对其进行编码:

#!/bin/bash
echo -n "-> "; for a in "$@"; do echo -n "\"$a\" "; done; echo

假设您将其另存为 show 在当前目录中并使其可执行,以下是如何执行的它有效:

$ ./show one two 'three and four'
-> "one" "two" "three and four" 

现在,如果原来的问题确实是关于上面的第 2 点(正如我认为的那样,在读了几次之后),并且应该像这样阅读(更改为粗体):

如何让 xargs 对给定输入的每个参数执行命令一次? 它的默认行为是将输入分块为参数,并尽可能少地执行命令,并将多个参数传递给每个实例。嗯>


那么答案是-n 1

让我们比较一下 xargs 的默认行为,它将输入围绕空格分割并尽可能少地调用命令:

$ echo one two 'three and four' | xargs ./show 
-> "one" "two" "three" "and" "four" 

及其与 -n 1 的行为:

$ echo one two 'three and four' | xargs -n 1 ./show 
-> "one" 
-> "two" 
-> "three" 
-> "and" 
-> "four" 

另一方面,如果原始问题是关于第1点.输入分割,它应该这样读(很多人来到这里似乎认为是这样,或者混淆了两个问题):

如何让 xargs 对给定的每一行输入使用精确一个参数执行命令? 它的默认行为是将行围绕空白进行分块。

那么答案就更微妙了。

人们可能会认为 -L 1 可能会有所帮助,但事实证明它不会改变参数解析。 它只对每个输入行执行一次命令,并使用与该输入行上的参数一样多的参数:

$ echo 

不仅如此,如果一行以空格结尾,它会附加到下一行:

$ echo 

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

$ echo 

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

$ echo 

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

$ echo 
one\ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" 
-> "two" 
-> "three" "and" "four" 

不仅如此,如果一行以空格结尾,它会附加到下一行:


显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:


现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):


如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:


one \ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" "two" 
-> "three" "and" "four" 

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:


现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):


如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:


one\ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" 
-> "two" 
-> "three" "and" "four" 

不仅如此,如果一行以空格结尾,它会附加到下一行:


显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:


现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):


如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:


one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show 
-> "one " "two" "three and four" 

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):


如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:


one\ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" 
-> "two" 
-> "three" "and" "four" 

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 ./show -> "one " -> "two" -> "three and four"

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show -> "one " "two" "three and four"

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | xargs -d\\n -n1 ./show -> "one " -> "two" -> "three and four" one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show -> "one " "two" "three and four"

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 ./show -> "one " -> "two" -> "three and four"

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show -> "one " "two" "three and four"

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

不仅如此,如果一行以空格结尾,它会附加到下一行:

显然, -L< /code> 并不是要改变 xargs 将输入拆分为参数的方式。

以跨平台方式(不包括 GNU 扩展)执行此操作的唯一参数是 -0,它将输入围绕 NUL 字节进行分割。

然后,只需在 tr 的帮助下将换行符转换为 NUL 即可:

现在参数解析看起来没问题,包括尾随空格。

最后,如果将此技术与 -n 1 结合起来,无论您有什么输入,每个输入行都会执行一个命令,这可能是查看原始问题的另一种方式(可能是最常见的)直观,给定标题):

如上所述,如果您使用 GNU xargs,您可以将 tr 替换为 GNU 特定选项 -d >:

It seems to me all existing answers on this page are wrong, including the one marked as correct. That stems from the fact that the question is ambiguously worded.

Summary:   If you want to execute the command "exactly once for each line of input," passing the entire line (without newline) to the command as a single argument, then this is the best UNIX-compatible way to do it:

... | tr '\n' '\0' | xargs -0 -n1 ...

If you are using GNU xargs and don't need to be compatible with all other UNIX's (FreeBSD, Mac OS X, etc.) then you can use the GNU-specific option -d:

... | xargs -d\\n -n1 ...

Now for the long explanation…


There are two issues to take into account when using xargs:

  1. how does it split the input into "arguments"; and
  2. how many arguments to pass the child command at a time.

To test xargs' behavior, we need an utility that shows how many times it's being executed and with how many arguments. I don't know if there is a standard utility to do that, but we can code it quite easily in bash:

#!/bin/bash
echo -n "-> "; for a in "$@"; do echo -n "\"$a\" "; done; echo

Assuming you save it as show in your current directory and make it executable, here is how it works:

$ ./show one two 'three and four'
-> "one" "two" "three and four" 

Now, if the original question is really about point 2. above (as I think it is, after reading it a few times over) and it is to be read like this (changes in bold):

How can I make xargs execute the command exactly once for each argument of input given? Its default behavior is to chunk the input into arguments and execute the command as few times as possible, passing multiple arguments to each instance.

then the answer is -n 1.

Let's compare xargs' default behavior, which splits the input around whitespace and calls the command as few times as possible:

$ echo one two 'three and four' | xargs ./show 
-> "one" "two" "three" "and" "four" 

and its behavior with -n 1:

$ echo one two 'three and four' | xargs -n 1 ./show 
-> "one" 
-> "two" 
-> "three" 
-> "and" 
-> "four" 

If, on the other hand, the original question was about point 1. input splitting and it was to be read like this (many people coming here seem to think that's the case, or are confusing the two issues):

How can I make xargs execute the command with exactly one argument for each line of input given? Its default behavior is to chunk the lines around whitespace.

then the answer is more subtle.

One would think that -L 1 could be of help, but it turns out it doesn't change argument parsing. It only executes the command once for each input line, with as many arguments as were there on that input line:

$ echo 

Not only that, but if a line ends with whitespace, it is appended to the next:

$ echo 

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

$ echo 

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

$ echo 

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

$ echo 
one\ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" 
-> "two" 
-> "three" "and" "four" 

Not only that, but if a line ends with whitespace, it is appended to the next:


Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:


Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):


As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:


one \ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" "two" 
-> "three" "and" "four" 

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:


Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):


As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:


one\ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" 
-> "two" 
-> "three" "and" "four" 

Not only that, but if a line ends with whitespace, it is appended to the next:


Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:


Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):


As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:


one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show 
-> "one " "two" "three and four" 

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):


As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:


one\ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" 
-> "two" 
-> "three" "and" "four" 

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 ./show -> "one " -> "two" -> "three and four"

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show -> "one " "two" "three and four"

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | xargs -d\\n -n1 ./show -> "one " -> "two" -> "three and four" one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show -> "one " "two" "three and four"

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 ./show -> "one " -> "two" -> "three and four"

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show -> "one " "two" "three and four"

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one \ntwo\nthree and four' | xargs -L 1 ./show -> "one" "two" -> "three" "and" "four"

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

one\ntwo\nthree and four' | xargs -L 1 ./show -> "one" -> "two" -> "three" "and" "four"

Not only that, but if a line ends with whitespace, it is appended to the next:

Clearly, -L is not about changing the way xargs splits the input into arguments.

The only argument that does so in a cross-platform fashion (excluding GNU extensions) is -0, which splits the input around NUL bytes.

Then, it's just a matter of translating newlines to NUL with the help of tr:

Now the argument parsing looks all right, including the trailing whitespace.

Finally, if you combine this technique with -n 1, you get exactly one command execution per input line, whatever input you have, which may be yet another way to look at the original question (possibly the most intuitive, given the title):

As mentioned above, if you are using GNU xargs you can replace the tr with the GNU-specific option -d:

深居我梦 2024-07-13 19:45:32

如果您想对来自 find每一行(即结果)运行命令,那么您需要 xargs 做什么?

尝试:

find 路径 -type f -exec 你的命令 {} \;

其中文字 {} 被文件名替换,并且 find 需要文字 \; 才能知道自定义命令在此结束。

编辑:(

在编辑问题后澄清您了解 -exec

来自 man xargs

-L 最大行数
每个命令行最多使用 max-lines 个非空白输入行。 尾随
空白导致输入行在逻辑上继续到下一个输入行。
意味着 -x。

请注意,如果您使用 xargs,以空格结尾的文件名会给您带来麻烦:

$ mkdir /tmp/bax; cd /tmp/bax
$ touch a\  b c\  c
$ find . -type f -print | xargs -L1 wc -l
0 ./c
0 ./c
0 total
0 ./b
wc: ./a: No such file or directory

因此,如果您不关心 -exec 选项,最好使用 -print0-0

$ find . -type f -print0 | xargs -0L1 wc -l
0 ./c
0 ./c
0 ./b
0 ./a

If you want to run the command for every line (i.e. result) coming from find, then what do you need the xargs for?

Try:

find path -type f -exec your-command {} \;

where the literal {} gets substituted by the filename and the literal \; is needed for find to know that the custom command ends there.

EDIT:

(after the edit of your question clarifying that you know about -exec)

From man xargs:

-L max-lines
Use at most max-lines nonblank input lines per command line. Trailing
blanks cause an input line to be logically continued on the next input line.
Implies -x.

Note that filenames ending in blanks would cause you trouble if you use xargs:

$ mkdir /tmp/bax; cd /tmp/bax
$ touch a\  b c\  c
$ find . -type f -print | xargs -L1 wc -l
0 ./c
0 ./c
0 total
0 ./b
wc: ./a: No such file or directory

So if you don't care about the -exec option, you better use -print0 and -0:

$ find . -type f -print0 | xargs -0L1 wc -l
0 ./c
0 ./c
0 ./b
0 ./a
慵挽 2024-07-13 19:45:32

这两种方法也有效,并且适用于不使用 find 的其他命令!

xargs -I '{}' rm '{}'
xargs -i rm '{}'

示例用例:

find . -name "*.pyc" | xargs -i rm '{}'

将删除该目录下的所有 pyc 文件,即使 pyc 文件包含空格。

These two ways also work, and will work for other commands that are not using find!

xargs -I '{}' rm '{}'
xargs -i rm '{}'

example use case:

find . -name "*.pyc" | xargs -i rm '{}'

will delete all pyc files under this directory even if the pyc files contain spaces.

少钕鈤記 2024-07-13 19:45:32

如何让 xargs 对给定的每一行输入精确执行一次命令?

-L 1 是简单的解决方案,但如果任何文件中包含空格,则它不起作用。 这是 find 的 -print0 参数的关键功能 - 用“\0”字符而不是空格分隔参数。 下面是一个示例:

echo "file with space.txt" | xargs -L 1 ls
ls: file: No such file or directory
ls: with: No such file or directory
ls: space.txt: No such file or directory

更好的解决方案是使用 tr 将换行符转换为空 (\0) 字符,然后使用 xargs -0争论。 下面是一个示例:

echo "file with space.txt" | tr '\n' '\0' | xargs -0 ls
file with space.txt

如果您需要限制调用次数,您可以使用 -n 1 参数为每​​个输入对程序进行一次调用:

echo "file with space.txt" | tr '\n' '\0' | xargs -0 -n 1 ls

这还允许您过滤 find 的输出将中断转换为空之前。

find . -name \*.xml | grep -v /target/ | tr '\n' '\0' | xargs -0 tar -cf xml.tar

How can I make xargs execute the command exactly once for each line of input given?

-L 1 is the simple solution but it does not work if any of the files contain spaces in them. This is a key function of find's -print0 argument – to separate the arguments by '\0' character instead of whitespace. Here's an example:

echo "file with space.txt" | xargs -L 1 ls
ls: file: No such file or directory
ls: with: No such file or directory
ls: space.txt: No such file or directory

A better solution is to use tr to convert newlines to null (\0) characters, and then use the xargs -0 argument. Here's an example:

echo "file with space.txt" | tr '\n' '\0' | xargs -0 ls
file with space.txt

If you then need to limit the number of calls you can use the -n 1 argument to make one call to the program for each input:

echo "file with space.txt" | tr '\n' '\0' | xargs -0 -n 1 ls

This also allows you to filter the output of find before converting the breaks into nulls.

find . -name \*.xml | grep -v /target/ | tr '\n' '\0' | xargs -0 tar -cf xml.tar
阳光的暖冬 2024-07-13 19:45:32

另一种选择...

find /path -type f | while read ln; do echo "processing $ln"; done

Another alternative...

find /path -type f | while read ln; do echo "processing $ln"; done
吃素的狼 2024-07-13 19:45:32
find path -type f | xargs -L1 command 

是你所需要的全部。

find path -type f | xargs -L1 command 

is all you need.

夜光 2024-07-13 19:45:32

以下命令将查找 /path 中的所有文件(-type f),然后使用 cp 将它们复制到当前文件夹。 请注意,使用 if -I % 在 cp 命令行中指定占位符,以便可以将参数放置在文件名之后。

查找 /path -type f -print0 | xargs -0 -I % cp % .

使用 xargs (GNU findutils) 4.4.0 进行测试

The following command will find all the files (-type f) in /path and then copy them using cp to the current folder. Note the use if -I % to specify a placeholder character in the cp command line so that arguments can be placed after the file name.

find /path -type f -print0 | xargs -0 -I % cp % .

Tested with xargs (GNU findutils) 4.4.0

情徒 2024-07-13 19:45:32

您可以分别使用 --max-lines 或 --max-args 标志来限制行数或参数数(如果每个参数之间有空格)。

<前><代码> -L 最大行数
每个命令行最多使用 max-lines 非空白输入行。 尾随空白导致输入行在下一个输入中逻辑上继续
线。 意味着-x。

--max-lines[=最大行数], -l[最大行数]
-L 选项的同义词。 与 -L 不同,max-lines 参数是可选的。 如果未指定 max-args,则默认为 1。 -l 选项
已弃用,因为 POSIX 标准指定 -L 代替。

--max-args=最大参数, -n 最大参数
每个命令行最多使用 max-args 个参数。 如果超出大小(请参阅 -s 选项),则将使用少于 max-args 的参数,
除非给出 -x 选项,在这种情况下 xargs 将退出。

You can limit the number of lines, or arguments (if there are spaces between each argument) using the --max-lines or --max-args flags, respectively.

  -L max-lines
         Use at most max-lines nonblank input lines per command line.  Trailing blanks cause an input line to be logically continued on the next  input
         line.  Implies -x.

  --max-lines[=max-lines], -l[max-lines]
         Synonym  for  the -L option.  Unlike -L, the max-lines argument is optional.  If max-args is not specified, it defaults to one.  The -l option
         is deprecated since the POSIX standard specifies -L instead.

  --max-args=max-args, -n max-args
         Use at most max-args arguments per command line.  Fewer than max-args arguments will be used if the size (see  the  -s  option)  is  exceeded,
         unless the -x option is given, in which case xargs will exit.
暗地喜欢 2024-07-13 19:45:32

@Draemon 的答案似乎是正确的“-0”,即使文件中有空格。

我正在尝试 xargs 命令,发现“-0”与“-L”完美配合。 甚至空格也会被处理(如果输入以 null 终止)。 下面是一个示例:

#touch "file with space"
#touch "file1"
#touch "file2"

下面将分割空值并在列表中的每个参数上执行命令:

 #find . -name 'file*' -print0 | xargs -0 -L1
./file with space
./file1
./file2

因此如果与“-0”一起使用,-L1将在每个空终止字符上执行参数。 要查看差异,请尝试:

 #find . -name 'file*' -print0 | xargs -0 | xargs -L1
 ./file with space ./file1 ./file2

即使这将执行一次:

 #find . -name 'file*' -print0  | xargs -0  | xargs -0 -L1
./file with space ./file1 ./file2

该命令将执行一次,因为“-L”现在不会在空字节上拆分。 您需要同时提供“-0”和“-L”才能工作。

@Draemon answers seems to be right with "-0" even with space in the file.

I was trying the xargs command and I found that "-0" works perfectly with "-L". even the spaces are treated (if input was null terminated ). the following is an example :

#touch "file with space"
#touch "file1"
#touch "file2"

The following will split the nulls and execute the command on each argument in the list :

 #find . -name 'file*' -print0 | xargs -0 -L1
./file with space
./file1
./file2

so -L1 will execute the argument on each null terminated character if used with "-0". To see the difference try :

 #find . -name 'file*' -print0 | xargs -0 | xargs -L1
 ./file with space ./file1 ./file2

even this will execute once :

 #find . -name 'file*' -print0  | xargs -0  | xargs -0 -L1
./file with space ./file1 ./file2

The command will execute once as the "-L" now doesn't split on null byte. you need to provide both "-0" and "-L" to work.

花海 2024-07-13 19:45:32

我似乎没有足够的声誉来添加评论 Tobia 的答案上面,所以我添加这个“答案”帮助我们这些想要在 Windows 平台上以同样的方式试验 xargs 的人。

这是一个 Windows 批处理文件,它与 Tobia 的快速编码的“show”脚本执行相同的操作:

@echo off
REM
REM  cool trick of using "set" to echo without new line
REM  (from:  http://www.psteiner.com/2012/05/windows-batch-echo-without-new-line.html)
REM
if "%~1" == "" (
    exit /b
)

<nul set /p=Args:  "%~1"
shift

:start
if not "%~1" == "" (
    <nul set /p=, "%~1"
    shift
    goto start
)
echo.

It seems I don't have enough reputation to add a comment to Tobia's answer above, so I am adding this "answer" to help those of us wanting to experiment with xargs the same way on the Windows platforms.

Here is a windows batch file that does the same thing as Tobia's quickly coded "show" script:

@echo off
REM
REM  cool trick of using "set" to echo without new line
REM  (from:  http://www.psteiner.com/2012/05/windows-batch-echo-without-new-line.html)
REM
if "%~1" == "" (
    exit /b
)

<nul set /p=Args:  "%~1"
shift

:start
if not "%~1" == "" (
    <nul set /p=, "%~1"
    shift
    goto start
)
echo.
旧城烟雨 2024-07-13 19:45:32

在您的示例中,将 find 的输出通过管道传输到 xargs 的目的是 find 的 -exec 选项的标准行为是为每个找到的文件执行一次命令。 如果您正在使用 find,并且想要它的标准行为,那么答案很简单 - 一开始就不要使用 xargs。

In your example, the point of piping the output of find to xargs is that the standard behavior of find's -exec option is to execute the command once for each found file. If you're using find, and you want its standard behavior, then the answer is simple - don't use xargs to begin with.

陪你到最终 2024-07-13 19:45:32

对当前或子文件夹中的每个 build.xml 执行 ant 任务 clean-all 。

find . -name 'build.xml' -exec ant -f {} clean-all \;

execute ant task clean-all on every build.xml on current or sub-folder.

find . -name 'build.xml' -exec ant -f {} clean-all \;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文