Назад | Перейти на главную страницу

Как удалить последние n строк файла без копирования?

Размер файла журнала: 10 ГБ

Свободное место в разделе: 6 ГБ

Необходимо разделить файл журнала на более мелкие части и сжать их. Но недостаточно места для запуска чего-то вроде split (1), что оставляет исходный файл нетронутым. Это оставит нас с

Исходный файл журнала: 10 ГБ

Вывод сплита: еще 10 ГБ

Есть ли способ разделить файл внутри файла или сделать что-то вроде этого:

$ tail -nnn bigfile.txt> кусок.txt

$ some-command -nnn bigfile.txt # просто обрезать последние nnn строк

$ gzip piece.txt

(повторение)

Было бы неплохо найти такую ​​утилиту, как "some-command".

Вот как бы я это сделал -

Решите, сколько строк журнала вы хотите в одном разделенном файле. Вам также необходимо убедиться, что у вас есть свободное пространство, равное размеру разделенного файла. Скажем, 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

вы могли бы использовать split команда вы можете определить байты, размер, строки:

split -db 10k bigfile.txt bigfile_

Примечание: выходной файл будет bigfile_N, потому что мы используем ключ -d.

используя переключатель -l, мы можем определить количество строк, например:

split -dl 1000 bigfile.txt bigfile_

Затем вы можете периодически останавливать задание (Ctrl + Z) и архивировать части, а затем использовать «fg» для возобновления остановленного задания.