这看上去是一个微不足道的问题,但我却始终找不到解决办法。
我想清除许多文本文件和日志文件。原因是什么?为了节省磁盘空间。
对于一个文本文件,这很简单echo '' > path/to/file.txt
但是文件太多了。我只能使用find
和xargs
。但我不知道该怎么解决“输入重定向”。
我试过了,find . -name <regex> | xargs -I target echo '' > target
但echo '' > { 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