xargs 参数重定向

iGb*_*nam 4 terminal shell-script xargs input

这似乎是一个微不足道的问题,但解决方案让我如此谨慎。

我想清除很多文本文件;日志文件。原因?为了节省磁盘空间。

使用一个文本文件,这很简单 echo '' > path/to/file.txt

但是,文件很多。我已经求助于使用findxargs。但我不知道如何绕过“输入重定向”

我试过find . -name <regex> | xargs -I target echo '' > targetecho '' > { find . -name <regex> | xargs -I target target }; 没有工作

我不精通 shell 脚本,不胜感激。

谢谢。

Ala*_*rry 11

您在两个示例中所做的都是>当前shell 可以看到的位置放在当前shell 可以看到的位置,因此在 find 和 xargs 命令运行之前,重定向只执行一次。那是你的第一个问题。

您的第二个问题是,如果您引用 the>以便将其传递给xargs,它仍然无法工作,因为xargs除非您要求,否则不会通过 shell 传递您的命令。

你的第三个问题是,如果你确实告诉 xargs 使用 shell 来运行命令,那么如果任何文件名中包含有趣的字符,shell 就会做错事。(此外, xargs 对有趣的角色本身做了错误的处理,但这可以用-0.修复。)

您可能还不关心的其他问题包括:

  • echo''不会创建一个空文件,而是一个包含换行符的文件。
  • -name选项采用 glob,而不是正则表达式。
  • 您可能想要添加-type f以防万一任何目录与 glob 匹配。

这是命令的部分更正版本:

find . -name '*thisisaglob*' -type f -print0 |
xargs -0 -I target sh -c ': > target'
Run Code Online (Sandbox Code Playgroud)

这解决了我提到的大部分问题。仍然存在 shell 误解包含 shell 元字符的文件名的问题。要解决这个问题,您必须将文件名作为参数而不是-c命令的一部分提供给 shell 。那看起来像这样:

find . -name '*thisisaglob*' -type f -print0 |
xargs -0 -I target sh -c ': > "$1"' fnord target
Run Code Online (Sandbox Code Playgroud)

“fnord”是一个占位符。它变成$0了我们不需要的东西。

现在已经安全地实现了同时使用 xargs 和重定向的目标,我将向您展示如何通过不使用它们来实现您的目标。

find . -name '*thisisaglob*' -type f -exec truncate -s 0 '{}' +
Run Code Online (Sandbox Code Playgroud)

这需要truncate命令,它是 GNU coreutils 的一部分而不是 unix 标准实用程序,所以它的便携性较差,但更容易阅读,不是吗?