Обрезать половину очень большого файла

339
tannerli

Мы позволили журналу трассировки работать в нашей продуктивной системе, и его размер вырос почти до 50 ГБ, что привело к тому, что диск работал почти полностью. Я остановил трассировку, чтобы файл больше не рос. Мне не нужен весь файл, но я также не хочу удалять все это и сохранять последние несколько ГБ или около того.

То, что я думал и отклонил:

  • Усечение файла приведет к потере последних нескольких гигабайт данных, которые я хочу сохранить.
  • PowerShell gc | select -last 1000сканирует вперед и работает вечно даже для файла 5 ГБ (Интересно, что команда использовала более 8 ГБ ОЗУ для файла 5 ГБ, прежде чем я его уничтожил)
  • Перенос файла для сохранения невозможен (это сайт клиента)

Есть ли какая-нибудь другая одноразовая магическая команда оболочки, которая может разрезать файл пополам и получить желаемый размер повторяющимися половинками?

Или, может быть, способ разбить файл на куски? (Это должно быть сделано на месте, нет места для полной копии файла)

1
В Linux есть `fallocate --punch-hole`, который сбрасывает данные и делает файл разреженным; Вы не можете использовать его с NTFS, хотя. Я надеюсь, что есть что-то подобное для Windows и ее файловых систем. Kamil Maciorowski 5 лет назад 0
@KamilMaciorowski для "неправильного" совета. Это все еще пригодится мне, поскольку я обычно на Linux :-) tannerli 5 лет назад 0
Теперь я вижу, что `fallocate --collapse-range` может быть еще более полезным в подобной ситуации. Удачи с Windows. Kamil Maciorowski 5 лет назад 0
Удивительно, сколько замечательных инструментов мне еще предстоит открыть, даже после почти 10-летнего опыта работы с Linux. На данный момент похоже, что я просто урежу файл в Windows и назову его через день. tannerli 5 лет назад 0
Также в Linux вы можете сделать что-то вроде `tail -100000 [filename]> [new filename]; rm [имя файла] `, чтобы сохранить последние 100 000 строк для анализа. Mike Scott 5 лет назад 0
@MikeScott того, что я подумал сам. Afaik, у Powershell нет команды, сканирующей хвост в обратном направлении. tannerli 5 лет назад 0

1 ответ на вопрос

1
harrymc

Есть много возможностей для разделения и объединения большого файла.

Если вы примете стороннюю бесплатную утилиту, вы можете использовать HJ Split или GSplit, но существует множество других.

Если вы хотите сохранить файл как единое целое и одновременно сжать его на куски, вы можете использовать 7Zip, где на экране «Добавить в архив» у вас есть поле « Разделить на тома», указывающее количество байтов для каждого чанка и некоторые больше вариантов.

Если вы предпочитаете сценарий PowerShell, вы можете использовать Split-File.ps1, который содержит функции разделения по размеру байта и объединения:

Split-File "BigFile.dat" 10000000 dir BigFile??.dat | Join-File Rebuild.dat 

Если вы используете подсистему Windows для Linux (WSL), вы можете использовать команды Linux для split и cat .

Если все, что вам нужно, это скопировать часть файла, вы можете использовать эту однострочную оболочку PowerShell, которая использует команды Get-Content и Set-Content :

$file = (Get-Content log.txt)[<from-line..<to-line>] | Set-Content logpart.txt 

Get-Contentтакже есть -Tailпараметр, о котором вы спрашивали, надеюсь, более эффективным способом.

Упомянутые инструменты на самом деле не вариант. Я не могу (или, по крайней мере, не должен) устанавливать новое программное обеспечение на сервер. Ссылка на «Split-File.ps», к сожалению, указывает на другой вопрос SU, который вы комментировали ... tannerli 5 лет назад 0
Упс - я исправил ссылку. harrymc 5 лет назад 0
Спасибо за (обновленную) ссылку на скрипт PowerShell. Как упоминалось в моем вопросе, я не могу создать (разделенную) копию файла, так как на диске уже заканчивается. Сценарий должен удалять каждую порцию обработанных данных по мере продолжения, что снова ставит вопрос о том, как удалить первые ГБ (или около того) файла. tannerli 5 лет назад 0
Вы не можете использовать внешний диск? harrymc 5 лет назад 0
Нет я не могу Это машина клиента, расположенная ... где-то в Интернете, с моей точки зрения tannerli 5 лет назад 0
Я добавил еще одну команду PowerShell, которая может помочь. harrymc 5 лет назад 0
Параметр `-Tail` для` Get-Content`, похоже, меняет порядок сканирования. Благодаря этому я смог извлечь последние 100 тыс. Строк в отдельный файл. Теперь я могу спокойно удалить остальное. Спасибо tannerli 5 лет назад 0
Вопрос говорит о 50 ГБ файлах, и все упомянутые решения PowerShell буферизуют все данные в памяти. Это будет очень неэффективно. Должно быть решение с использованием API файловой системы ... George Chakhidze 5 лет назад 0
@ GeorgeChakhidze: Буферизация с диска на диск невозможна - данные должны передаваться по ОЗУ. harrymc 5 лет назад 0