У меня есть большое количество файлов, некоторые из которых очень длинные. Я хотел бы обрезать их до определенного размера, если они больше, удалив конец файла. Но я хочу только удалить целые строки. Как я могу это сделать? Это похоже на то, что будет обрабатываться инструментарием Linux, но я не знаю правильной команды.
Например, скажем, у меня есть файл размером 120000 байт с 300-байтовыми строками, и я пытаюсь обрезать его до 10000 байт. Первые 33 строки должны остаться (9900 байт), а остальные должны быть обрезаны. Я не хочу точно вырезать 10 000 байт, так как это оставит частичную строку.
Конечно, файлы имеют разную длину, а строки имеют разную длину.
В идеале результирующие файлы должны быть немного короче, чем чуть длиннее (если точка останова находится на длинной строке), но это не так важно, это может быть немного длиннее, если это будет проще. Я хотел бы, чтобы изменения были внесены непосредственно в файлы (ну, возможно, новый файл скопирован в другом месте, оригинал удален, а новый файл перемещен, но это то же самое из пользовательского POV). Решение, которое перенаправляет данные в кучу мест, а затем обратно предлагает возможность повреждения файла, и я хотел бы избежать этого ...
источник
Ответы:
sed
/wc
Сложность можно избежать в предыдущих ответах , еслиawk
используется. Используя пример, предоставленный из OP (показаны полные строки до 10000 байт):Также показывает полную строку, содержащую 10000-й байт, если этот байт не находится в конце строки:
Ответ выше предполагает:
\n
). Для текстовых файлов Dos / Windows (\r\n
) изменитеlength() + 1
наlength() + 2
LC_CTYPE=C
принудительную интерпретацию на уровне байтов.источник
sed
Подход хорошо, но в цикле по всем линиям не является. Если вы знаете, сколько строк вы хотите сохранить (для примера, я использую здесь 99), вы можете сделать это следующим образом:Пояснение:
sed
это процессор регулярных выражений. С указанным параметром-i
он обрабатывает файл напрямую («inline»), а не просто читает его и записывает результаты в стандартный вывод.100,$
просто означает «от строки 100 до конца файла» - и сопровождается командойd
, которую вы, вероятно, догадались правильно, чтобы заменить «удалить». Короче говоря, команда означает: «Удалить все строки из строки 100 до конца файла из myfile.txt». 100 - это первая строка, которую нужно удалить, так как вы хотите сохранить 99 строк.Изменить: Если, с другой стороны, есть файлы журналов, где вы хотите сохранить, например, последние 100 строк:
Что здесь происходит:
[ $(wc -l myfile.txt) -gt 100 ]
: делать следующее, только если файл содержит более 100 строк$((100 - $(wc -l myfile.txt|awk '{print $1}')))
: вычислить количество удаляемых строк (т.е. сохранить все строки файла, кроме (последних) 100)1, $((..)) d
: удалить все строки от первой до расчетнойРЕДАКТИРОВАТЬ: так как вопрос был только что отредактирован, чтобы дать больше деталей, я включу эту дополнительную информацию вместе с моим ответом. Добавлены факты:
Из этих данных можно рассчитать количество строк, которые останутся как "/", что в примере будет означать 33 строки. Термин оболочки для вычисления:
$((size_to_remain / linesize))
(по крайней мере в Linux, использующем Bash, результат - целое число). Настроенная команда теперь будет выглядеть так:Поскольку размеры известны заранее, больше нет необходимости в вычислениях, встроенных в
sed
команду. Но для большей гибкости внутри некоторого сценария оболочки можно использовать переменные.Для условной обработки, основанной на размере файла, можно использовать следующую «тестовую» конструкцию:
что означает: «если размер
$file
превышает 100 КБ, делайте ...» (ls -lk
перечисляет размер файла в КБ в позиции 5, следовательноawk
, используется для извлечения именно этого).источник
head -n
.Не найдя команды для этого, я написал быстрый скрипт (не тестировался):
источник
Вы можете использовать команду linux sed для удаления строк из файла. Следующая команда удаляет последнюю строку filename.txt:
С помощью awk или find вы можете искать шаблон, соответствующий вашей команде sed. Сначала вы ищете с помощью awk или находите файлы, которые хотите сократить, а затем вы можете удалить строки с помощью sed.
источник
Я сделал что-то похожее с хвостом. Чтобы сохранить только последние 10000 строк в этом случае:
источник