使用“cat /dev/null”命令将多个文件清空,例如日志文件。

8

清理日志的好方法是通过syslog来处理文件。当我的Linux服务器空间不足时,我尝试了以下命令:cat /dev/null > fileABC; cat /dev/null/ > fileXYZ

如何使用一个高效或单个命令将cat /dev/null清除多个文件呢?


“cp dev/null/ whatever” 对我来说没有意义。null 是一个设备文件。 - Michał Šrajer
做了一些编辑..我的意思是将它连接起来。请检查此链接以清除现有文件的内容http://goo.gl/UJXEy3 - Srujan Kumar Gulla
@Samuel 你说得对。但是我如何一次处理10-15个文件呢? - Srujan Kumar Gulla
1
“/dev/null”通常是一个目标,而不是一个源。您的意思是要用空内容覆盖文件,并将其长度设置为0吗? - donjuedo
4
“>fileABC”的作用与使用“cat”命令无异。 - Charles Duffy
正如您在其他评论中所说的那样,@CharlesDuffy OR printf '' > fileABC。 - Srujan Kumar Gulla
3个回答

29

硬编码解决方案

tee

使用tee命令,将内容同时输出到多个文件而无需显示在终端上。

示例:

$ echo -n | tee file1 file2 file3 file4 file5

如果这个列表中的文件不存在,它们将被创建并保持为空。

应用到你的回答上就是:

如果这个列表中的文件不存在,它们将被创建并保持为空。

$ cat /dev/null | tee fileABC fileXYZ

虽然使用echo -ncat /dev/null更好,但正如Charles Duffy所指出的那样,更好的解决方案是使用printf ''。因此,得到以下命令:

$ printf '' | tee file1 file2 file3 

截断

正如skrilled所回答的那样,truncate可能是您最初正在寻找的解决方案。该命令允许提供任意多个文件名参数。您可以轻松地按照以下方式使用它:

$ truncate --size 0 file1 file2 file3 file4 file5

这个方法可以让你在单个命令中完成目标,无需使用管道,下面是skrilled提供的巧妙答案。

解决文件结构命名问题

如果所有文件都有结构化的命名(例如文件)和位置,你可以使用find命令。在下面的例子中,我将对当前目录及其所有子目录中的所有.java.c源文件应用删除操作。

$ find . -maxdepth 2 -type f -name '*.java' -exec truncate --size 0 "{}" \; 

解释:

  • find .在当前目录下执行find
  • -maxdepth 2递归级别,进入目录但不再深入(级别2)。将其设置为1以防止进一步进入或n进入n次。
  • -type f仅应用于文件,而不是目录
  • -name '*.java'仅应用于以.java结尾的文件
  • -exec truncate --size 0 "{}" \;截断找到的每个文件(文件名存储在{}中)

请参见man find以获取更多选项和更详细的说明。务必查看它,因为find是自动化文件编辑中最强大的工具之一。

分文件列表解决方案

最简单的方法可能是逐行将要删除的文件存储在一个名为erasure的文件中。如果它们的位置和名称没有明显的结构。

假设文件存储在名为erasure 的文件中。

$ cat erasure
fileABC
fileXYZ
dir/anotherFile

在这个示例中,我们将删除上面列出的三个文件。

$ while read file; do > "$file"; done < erasure

解释:

  • while read file 对于给定文件中的每一行,将该行存储在变量file中。
  • do > "$file" 清空该文件并不输出任何内容(即擦除该文件)
  • done < erasure 使用<(重定向)指定输入文件。

注意:虽然这种方法保留了路径中的空格,但无法处理反斜杠和尾随空格,正如Charles Duffy所指出的那样。修复这两个问题的一种方法是将循环修改如下:

while IFS= read -r file; do > "$file"; done < erasure

然而,文件名中的换行符仍然是一个问题。解决此问题的唯一方法是使用空终止符 (\0) 分隔文件名。正确的循环现在变成:

while IFS= read -r -d '' file; do > "$file"; done < erasure

谢谢。cat /dev/null | tee fileABC fileXYZ 可以工作,但我不理解 echo 命令,为什么要在这里使用它。第二个代码片段就足够了,对吗?我有遗漏什么吗? - Srujan Kumar Gulla
1
它们是等价的,echo -n 是零输出,被认为比 cat /dev/null 更好的实践。如果答案有帮助,请不要忘记接受并点赞。 - ShellFish
1
@ShellFish,我认为printf''echo -n更好的做法--请参阅http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html中的POSIX echo规范,并注意,虽然-n是BSD echo的一部分,但它在SysV派生规范中不存在。 - Charles Duffy
1
至于“while read file”方法,它存在相当多的漏洞。例如,它无法正确处理含有字面反斜杠的文件名(需要使用“read -r”);不能处理文件名末尾有空格的文件(可以使用“IFS= read”解决);无法处理包含字面换行符的文件名(如果仍然使用基于行而不是基于NUL分隔的输入,则无法修复该问题)。 - Charles Duffy
1
哇,这才是我们所说的全面回答。太棒了! - Darragh Enright
显示剩余5条评论

5

Truncate也可用于清空文件。

truncate --size 0 /path/to/file/here

我没有在我的盒子上安装truncate,但是没问题..那样可以,但是我能否将多个文件列在一起?比如:"truncate --size 0 log1 log2 log3"? - Srujan Kumar Gulla
1
"truncate"的确是最佳解决方案,但主要问题在于处理多个文件。虽然"truncate"确实支持多个文件,但应该在回答中提到以明确给提问者解惑。所以我只需要将另一个文件名附加到命令中即可。虽然如此,你的回答很好,如果我的回答被接受,我会把这一点包含在答案中,如果你同意的话(当然,你会被列为贡献者)。 - ShellFish

0

你可以使用GNU Parallel来优雅地完成它:

parallel '>' ::: TooLong.log BigBoy.dat NonExistant.file

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接