如何在不复制的情况下删除文件的最后 n 行?

如何在不复制的情况下删除文件的最后 n 行?

日志文件大小:10 GB

分区中的可用空间:6 GB

需要将日志文件拆分成更小的部分,然后对其进行 gzip 压缩。但没有足够的空间来运行 split(1) 之类的操作,这样可以保留原始文件。这样我们就只能

原始日志文件:10 GB

分割输出:另外 10 GB

有没有办法在线拆分文件,或者执行以下操作:

$ tail -nnn bigfile.txt > piece.txt

$ some-command -nnn bigfile.txt # 只截断最后 nnn 行

$ gzip 片段.txt

(重复)

找到像“some-command”这样的实用程序也是可以的。

答案1

我会这样做 -

确定一个分割文件中要包含多少行日志。您还需要确保有等于分割文件大小的可用空间。我们假设为 10000 行,仅作为示例。

首先,将日志行复制到目标文件中

 head -n 10000 source.log | gzip -c > split001.log.gz

接下来,使用 sed 就地删除刚刚复制的行

 sed -i '1,10000d' source.log

只需稍加努力,您就可以将上述内容包装在一个脚本中,该脚本循环运行直到源文件为空,并在此过程中增加分割文件名。

- - 编辑 - -

好吧,我就不给你添麻烦了——

 #!/bin/bash

 if [ $# -ne 3 ]
 then
    echo "usage:  $0 <source file> <target prefix> <N lines per chunk>"
    exit
 fi

 filename=$1
 target_stem=$2
 target_lines=$3

 numlines=`wc -l $filename | cut -f1 -d' '`
 count=1;
 while [ $numlines -gt 0 ] 
 do
    head -n $target_lines $filename | gzip -c > ${target_stem}${count}.txt.gz
    sed -i "1,${target_lines}d" $filename

    numlines=`wc -l $filename | cut -f1 -d' '`
    let "count = $count + 1"
 done

答案2

您可以使用split命令来定义字节、大小、行:

split -db 10k bigfile.txt bigfile_

注意:由于我们使用了 -d 开关,因此输出文件将是 bigfile_N。

使用开关 -l 我们可以定义行数,例如:

split -dl 1000 bigfile.txt bigfile_

您可以定期停止作业(Ctrl + Z)并对这些片段进行 gzip 压缩,然后使用“fg”恢复已停止的作业。

相关内容