我有一个大小为130GB的大文件。
# ls -lrth
-rw-------. 1 root root 129G Apr 20 04:25 syslog.log
所以我需要删除以“Nov 2”开头的行来减小文件大小,所以我给出了以下命令,
sed -i '/Nov 2/d' syslog.log
所以我也无法使用VIM编辑器编辑文件。
当我触发SED命令时,它也会创建备份文件。但我根本没有太多空间。请尝试提供备用解决方案,以便从此文件中删除特定行,而不会增加服务器中的空间。
答案 0 :(得分:5)
它不会创建真正的备份文件。 sed
是流编辑器。当应用于带有选项-i
的文件时,它将通过sed
进程流式该文件,将输出写入 new 文件(临时一),当一切都完成后,它会将新文件重命名为原始名称。
(还有创建备份文件的选项,但是你没有给它们,所以我不会再提这些了。)
在您的情况下,您有一个非常大的文件,并且不想创建任何副本,无论多么临时。为此,您需要同时打开文件以阅读和,然后您的sed
进程可以覆盖原始文件。在此之后,您将不得不在写作结束时截断文件。
为了演示如何做到这一点,我们首先执行测试用例。
创建一个包含许多行的测试文件:
seq 0 999999 > x
现在,假设我们要删除包含数字4
的所有行:
grep -v 4 1<>x <x
这将打开文件读写为STDOUT(1),读取为STDIN。 grep
命令将读取所有行,并仅输出包含4
的行 (选项-v
)。
这将有效地覆盖原始文件的开头。
你不知道输出有多长,所以在输出后会出现文件的原始内容:
…
999991
999992
999993
999995
999996
999997
999998
999999
537824
537825
537826
537827
537828
537829
…
您可以使用Unix工具truncate
随后手动缩短文件。在实际情况中,您将难以找到适当的位置,因此计算写入的字节数是有意义的(使用wc
):
(不要忘记为此测试重新创建原始x
。)
(grep -v 4 <x | tee /dev/stderr 1<>x) |& wc -c
这将执行上述步骤并另外打印写入终端的字节数,在此示例中输出将为3653658
。现在使用truncate
:
truncate -s 3653658 x
现在你得到了你想要的结果。
如果你想在脚本中这样做,我。即没有互动,你可以使用这个:
length=$((grep -v 4 <x | tee /dev/stderr 1<>x) |& wc -c)
truncate -s "$length" x
我无法保证这适用于您机器上的&gt; 2GB或&gt; 4GB的文件;取决于您的操作系统(32位?)和已安装工具的版本,您可能会遇到大文件问题。我首先使用大文件执行测试(大约4GB,因为这通常是很多事情的限制),然后交叉手指并试一试:)
您必须牢记一些警告: