Основная команда sed для большого однострочного файла: не удалось перераспределить память

10

У меня есть текстовый файл 250 МБ, все в одной строке.

В этом файле я хочу заменить aсимволы на bсимволы:

sed -e "s/a/b/g" < one-line-250-mb.txt

Это терпит неудачу с:

sed: couldn't re-allocate memory

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


GNU sed версия 4.2.1
Ubuntu 12.04.2 LTS
1 ГБ ОЗУ

Николас Рауль
источник
4
Этот вопрос об очень сложном многострочном выражении. Мой вопрос о самом простом выражении, которое вы можете себе представить.
Николас Рауль
Плюс @RubanSavvy, ни один из ответов на другой вопрос не учитывает длинную линию, и фактически оба, вероятно, будут иметь одну и ту же проблему.
Тердон
Можете ли вы включить в этот вопрос свою версию sed, а также информацию об аппаратном обеспечении (особенно ОЗУ) и версию дистрибутива?
SLM

Ответы:

10

Да, используйте trвместо:

tr 'a' 'b' < file.txt > output.txt

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

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

Тердон
источник
Любопытно, что я только что создал файл размером 250 МБ, заполненный "abcabc ...", и смог обойтись sed -e "s/a/z/g" b.txt > c.txtбез проблем. Использование sed (GNU sed) 4.2.2.
SLM
То же самое @slm здесь для файла 496M и той же sedверсии, но это зависит от реализации или оборудования.
Terdon
Да, если бы мне нужно было сделать предположение, что мы имеем дело со старой версией sed.
SLM
5

Исторические версии sed и awk имели проблемы с памятью, в основном они были исправлены в более поздних версиях, но одно из классических проявлений этой проблемы довольно сильно ударило по Ларри Уоллу . его ответом было написать новый язык программирования - без ограничений памяти, кроме аппаратного. Он назвал это perl. Ваша конкретная проблема может быть решена более просто, но общее правило, которое я использую, - это когда sed не использует perl.

Редактировать: по запросу пример:

perl -pe "s/a/b/g" < one-line-250-mb.txt

или для меньшего использования памяти:

perl -e 'BEGIN{$/=\32768}' -pe "s/a/b/g" < one-line-250-mb.txt
hildred
источник
1
Весь этот абзац сводится к «Perl». Некоторые детали были бы хороши, или, по крайней мере, пример или что-то
Майкл Мрозек
@MichaelMrozek Я понимаю, что коллекция шляп действительно приводит к робоэдитингу, но я подумал, что с вашей репутацией вы бы обратили немного более пристальное внимание. Именно потому, что конкретная проблема уже была решена очень узким способом, который не поможет большинству людей, ищущих, поэтому я добавил ответ для общего случая. расширенный ответ, который я предоставил, помог бы Николасу Раулю, если бы еще не было работоспособного решения, но я сомневаюсь, что это помогло бы многим другим, тогда как мой первоначальный ответ помог бы всем, кто достиг предела sed. Если вы не согласны, я удалю
Hildred
@hildred Я не думаю, что это слишком много, чтобы спросить, что вы можете полагаться на добросовестность модераторов, когда они делают достоверные комментарии к вашему ответу, не прибегая сразу к обвинениям в скрытых мотивах (шляпы, правда ?!).
Крис Даун
@ChrisDown Напротив - я в этом полностью для шляп. Также это было помечено как не ответ несколькими людьми, но это отдаленный второй приоритет для шляп
Майкл Мрозек
Второй с ограничением памяти сделал свое дело (для моего однострочного файла объемом 2,5 ГБ): спасибо! sedХотя немного разочарован . : \
Томислав Накич-Альфиревич