xargs 参数重定向

xargs 参数重定向

这看上去是一个微不足道的问题,但我却始终找不到解决办法。

我想清除许多文本文件和日志文件。原因是什么?为了节省磁盘空间。

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

但是文件太多了。我只能使用findxargs。但我不知道该怎么解决“输入重定向”

我试过了,find . -name <regex> | xargs -I target echo '' > targetecho '' > { find . -name <regex> | xargs -I target target }都没用

我不太熟悉 shell 脚本,如能提供任何帮助我将不胜感激。

谢谢。

答案1

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

您的第二个问题是,如果您引用>以便将其传递给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'

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

find . -name '*thisisaglob*' -type f -print0 |
xargs -0 -I target sh -c ': > "$1"' fnord target

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

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

find . -name '*thisisaglob*' -type f -exec truncate -s 0 '{}' +

这需要truncate命令,它是 GNU coreutils 的一部分,而不是 unix 标准实用程序,因此它的可移植性较差,但更容易阅读,不是吗?

答案2

尽管 Alan Curry 的回答透彻、准确且知识渊博,但我有一个问题。为什么您希望文件继续存在,即使是空的?

我的建议是:

find . -name <glob> -print0 | xargs -0 rm

如果由于某种原因您需要这些文件存在,您可以执行一系列命令:

find . -name <glob> -print0 | tee /tmp/filelist | xargs -0 rm
cat /tmp/filelist | xargs -0 touch

如果你只是想压缩文件(例如,如果它们主要是冗余/重复的信息,但你想节省空间保留文件),您可以尝试:

find . -name <glob> -print0 | xargs -0 tar -xzf /tmp/logfiles.tgz

答案3

如果你有 GNU Parallelhttp://www.gnu.org/software/parallel/安装后你可以这样做:

find . -name '*thisisaglob*' -type f | parallel '>'

您可以通过以下方式轻松安装 GNU Parallel:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem

观看 GNU Parallel 的介绍视频以了解更多信息: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

相关内容