Недостаточно места на диске: удалите первые n строк текстового файла без копирования файла

Я хочу удалить первые строки $rmv огромного текстового файла с именем $filename . Этот текстовый файл настолько велик, что я не могу вместить две копии на моем жестком диске.

Следующее оставляет меня с пустым файлом с именем $filename :

 tail -n +$rmv "$filename" > "$filename" 

Невозможно выполнить следующее, потому что у меня нет места для хранения как $filename и $filename.tmp :

 tail -n +$rmv "$filename" > "$filename.tmp" && mv "$filename.tmp" "$filename" 

Если это имеет значение, я использую Mac OS X El Capitan.

Если у вас есть perl :

 { tail -n +"$rmi" perl -e 'truncate STDOUT, tell STDOUT' } <file 1<>file 

Обратите внимание, что при таком подходе нет резервной копии файла, поэтому любое повреждение заставляет вас потерять свои данные.

Я думаю, что ed не использует временные файлы, поэтому

 ed bigfile <<ED_SCRIPT 1,${rmv}d w q ED_SCRIPT 

Для редактирования сценариев файлов инструмент выбора – ex .

 ex -sc "1,${rmv}d | x" "$filename" 

Вы также можете посмотреть в утилиту split .

Ваш текстовый файл равен x MB, у вас нет 2 * x МБ, но, полагаю, у вас недостаточно места для сжатия файла? Текстовые файлы часто сжимаются до десятой части исходного размера …

У вас недостаточно места для хранения только строк ($ total- $ rmv), но что, если они сжаты? tail -n +$rmv "$filename" | gzip > "$filename.tmp" && zcat "$filename.tmp" > "$filename"

Принимая это как абстрактную интеллектуальную проблему, я бы разрезал файл в кусках, размер которых был либо поместим в память, либо в доступное дисковое пространство, начиная с последнего фрагмента и затем обрезая исходный файл. Я мог бы также сжать файл на месте, используя dd conv=notrunc .

Однако на практике я бы

  • скопируйте файл по сети на сервер с достаточным диском для хранения (только) строк ($ total- $ rmv), убедитесь, что я получил правильные строки, удаляю исходный файл и копирую обратно.

  • добавьте диск, поскольку вам это явно нужно.