清空文件内容的最有效方法

deb*_*bal 257 shell-script files truncate

我知道从文件中删除所有条目的三种方法。

他们是

  • >filename
  • touch filename1
  • filename < /dev/null

在这三个中,我滥用>filename最多,因为它需要最少的击键次数。

但是,我想知道就大日志文件和小文件而言,这三个中哪个最有效(如果有更有效的方法)。

另外,这三个代码是如何操作和删除内容的?


1编辑:正如在这个答案中所讨论的,这实际上并没有清除文件!

ash*_*ash 341

实际上,第二种形式touch filename不会从文件中删除任何内容——它只会在不存在的情况下创建一个空文件,或者更新现有文件的最后修改日期。

第三个filename < /dev/null尝试将文件名/dev/null作为输入运行。

cp /dev/null filename 作品。

至于效率,最有效率的是truncate -s 0 filename(见这里)。

否则,cp /dev/null filename或者> filename两者都很好。它们都使用 truncate-on-open 设置打开然后关闭文件。 cp也 opens /dev/null,所以这使它稍微慢一些。

另一方面,由于运行 truncate 命令需要系统打开可执行文件,加载它,然后运行它,truncate因此可能比> filename从脚本运行时慢。

  • 那么为什么说`truncate` 是最有效的呢? (11认同)
  • truncate 操作使用 ftruncate() 或 truncate() 系统调用,它不会打开文件。它还避免了 cp 和 `&gt; filename` 方法需要调用的 close() 系统调用。 (9认同)
  • 实际上,它(至少是 GNU 的)执行 open+ftruncate+close(除了它为加载和初始化自身所做的许多系统调用之外),无论如何,如果文件不存在,它将必须创建文件而 `truncate(2)` 不会这样做。 (3认同)

Art*_*ero 52

其他选择可能是:

echo -n > filename
Run Code Online (Sandbox Code Playgroud)

从手册页echo

-n Do not print the trailing newline character.


Mir*_*ner 7

有一个内置命令“:”,它可能在 sh、csh、bash 和其他命令中可用,它可以很容易地与重定向输出运算符一起使用,>截断文件:

#!/usr/bin/env bash
:> filename
Run Code Online (Sandbox Code Playgroud)

我喜欢的是,它不需要任何外部命令,如“echo”等。

截断文件而不是删除/重新创建文件的一大优点是,运行与此文件一起使用的应用程序(例如,某人制作tail -f filename或监视软件,...)不必重新打开它。他们可以继续使用文件描述符并获取所有新数据。

  • 有时,`&gt; 文件名` 不起作用。例如,在 zsh 中。但是`:&gt; filename` 仍然有效。 (2认同)