【问题标题】:Why is xargs not replacing the second {}为什么 xargs 不替换第二个 {}
【发布时间】:2020-10-08 07:56:35
【问题描述】:

我正在使用 xargs 来尝试回显文件的名称,然后是其内容。这是命令

find output/ -type f | xargs -I {} sh -c "echo {} ; cat {}"

但是由于某种原因,cat 之后的第二次替换没有被替换。仅适用于 一些 文件,因此某些文件确实可以正常工作。

需要明确的是,我不是在寻找可以让我回显文件名及其内容的命令,而是试图理解为什么这个特定命令不起作用。

【问题讨论】:

标签: xargs


【解决方案1】:

原来该命令太长了,所以它使用较短的文件名而无法使用较长的文件名。来自man xargs

-I replstr
             Execute utility for each input line, replacing one or more occurrences 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 255 bytes; this is implemented by concatenating as much
             of the argument containing replstr as possible, to the constructed arguments to utility, up to 255 bytes.  The 255 byte 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.

【讨论】:

  • 也来自手册页: -S replsize 指定 -I 可用于替换的空间量(以字节为单位)。 replsize 的默认值为 255。我可以通过指定 xargs -S 100000 -I {} <rest of command> 来使用带有长命令的 xargs。
  • 我对此进行了更多研究,并了解到我在 Linux 上运行时没有遇到命令长度问题,只有 mac os。我上面提到的手册页来自mac os。
【解决方案2】:

问题的根源在Carlos' answer中指出,但没有解决方案。

经过一番谷歌搜索,我找不到解除 255 个字符限制的方法。

因此,一种可能的解决方法是使用 shell 变量作为替代。

例子:

find . | xargs -I% sh -c 'F="%";iconv -f gb2312 -t utf-8 "$F">"$F.out";mv "$F.out" "$F"'

记得在最外面的sh -c参数字符串中使用单引号,我们不希望里面的$F被我们的父shell替换。

【讨论】:

  • 如果你必须使用双引号,你可以转义变量前面的 $ 以使子shell而不是父shell填充它
【解决方案3】:

文件名中带有空格的文件是否会造成问题?尝试添加 \",如下所示:

find output/ -type f | xargs -I {} sh -c "echo \"{}\" ; cat \"{}\""

这对我使用 Bash 很有用。

【讨论】:

  • 好主意,但在我的情况下没有空格
  • 这应该是一条评论。如果需要,您应该首先询问详细信息。请阅读:How to Answer
  • 假设您使用的是 Bash,如果您使用 set -x 然后运行您的命令,那么文件名不起作用的输出是什么?
猜你喜欢
  • 2017-12-03
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
相关资源
最近更新 更多