У меня есть файлы, которые были сгенерированы программой, которая не ставила переводы строк в конце записей. Я хочу поместить новые строки между записями, и я могу сделать это с помощью простого сценария sed:
sed -e 's/}{/}\n{/g'
Проблема заключается в том, что входные файлы имеют размер в несколько гигабайт, и поэтому строки ввода для sed имеют длину в несколько ГБ. sed пытается удерживать строку в памяти, которая в этом случае не работает. Я попробовал --unbuffered
вариант, но это, казалось, замедляло его и не позволяло закончить правильно.
tr
для перевода}
в\n
и затем использовать,sed
чтобы добавить}
в конце каждой строки? Как это:tr '}' '\n' < your_file.txt| sed 's/$/}/'
printf "\n" >> file
}{
повторения, пока его длины не станет несколько гигабайт, будет достаточно.dd if=file cbs=80 conv=unblock
сделал бы это - но это редко бывает так просто.Ответы:
Вы можете использовать другой инструмент, который позволяет вам установить разделитель входных записей. Например
Perl
Специальная переменная
$/
является разделителем входных записей. Установка его}{
определяет строки как заканчивающиеся на}{
. Таким образом, вы можете достичь того, что вы хотите, не читая все это в памяти.ястреб или ястреб
Это та же идея.
RS="}{"
устанавливает разделитель записей на,}{
а затем вы печатаете}
, новую строку{
(кроме первой записи) и текущую запись.источник
Perl на помощь:
Установка
$/
для\1024
прочтет файл в кусках 1024 байт. В$closing
переменной обрабатывает случай , когда кусок заканчивается в ,}
а следующий начинается с{
.источник
Ты должен сделать:
Это, наверное, самое эффективное решение.
Это позволяет
{}
защитить любые возможные конечные данные. С помощью еще одногоtr
процесса вы можете поменять его местами и сделать пустую строку в начале первого{
поля. Подобно...Итак, первое, с примерами Дона, делает:
... а второй делает ...
Для второго примера нет завершающего символа новой строки, хотя для первого - один.
источник
Бинарная
sed
утилита под названиемbbe
Я считаю, что в этом случае проще всего придерживаться подобного sed синтаксиса.
Я много предпочитаю с помощью
bbe
утилиты (доступна через ваш {универа, Linų} Установка пакета иксы, экapt-get
). Или здесь, если вы один из мерзавцев, хотя я лично не проверял эту конкретную ссылку.1. Поддерживает
s/before/after/
идиомуЭто «Binary Block Editor», который поддерживает sed-подобные (среди прочего) операции. Это включает в себя супер распространенную
s/before/after/
идиому замены, которая вам нужна. Обратите внимание, посколькуbbe
с точки зрения самой по себе нет строк, в конце команды нет «глобального g».В качестве быстрого теста (обратите внимание на обязательное
-e
):производит:
2. В вашем конкретном случае
}{
для}\n{
конвертацииПоэтому, если бы у нас был массивный файл, заполненный миллионами чисел в (скажем) формате
{1}{2}{3}
...{1000000}
без возврата каретки, мы могли бы легко обмениваться}{
с ними}\n{
и иметь все числа по одному в строке.Это было бы с этой
bbe
командой:Как проверено в этом цикле zsh, который мы берем только за хвост:
Который будет производить это:
(конечно, без возврата каретки)
источник