Основна команда 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 плюс, жодна з відповідей на інший Q не враховує довгий рядок, і насправді в обох, ймовірно, буде однакове питання.
terdon

Чи можете ви включити вашу версію sed у цей Q, а також інформацію про ваше обладнання (зокрема оперативна пам'ять) та дистрибутив?
slm

Відповіді:


10

Так, використовуйте trзамість цього:

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

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

tr з іншого боку, має справу з персонажами і має вміти правильно обробляти довгі рядки.


Цікаво, що я щойно створив файл на 250 МБ, заповнений w / "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 мали проблеми з пам'яттю, вони, як правило, були виправлені в більш пізніх версіях, але одне з класичних випадків цієї проблеми вдарило Ларрі Уолла досить важко. його відповідь полягала в тому, щоб написати нову мову програмування - без обмежень пам’яті, крім апаратних. Він назвав це перл. Вашу конкретну проблему можна вирішити простіше, але загальне правило, яке я використовую, це коли 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

1
Весь цей абзац зводиться до "Perl." Деякі деталі були б непоганими, або хоча б приклад чи щось таке
Майкл Мрозек

@MichaelMrozek Я розумію, що колекція капелюхів, як правило, призводить до роботизованості, але я подумав, що з твоєю репутацією ти звернеш трохи уважнішу увагу. Зокрема, в тому, що конкретна проблема вже була вирішена дуже вузьким способом, що не допомогло б більшості людей, які шукають, тому я додав відповідь на загальну справу. розширена відповідь, яку я надавав, допомогла б Ніколя Раулу Якби ще не було ефективного рішення, але я сумніваюсь, це допомогло б дуже багатьом іншим, тоді як моя оригінальна відповідь допомогла б усім, хто досяг межі sed. Якщо ви не погоджуєтесь, я
видаляю

@hildred Я не думаю, що занадто багато просити, щоб ти міг припустити добросовісність модераторів, коли вони роблять вагомі коментарі до твоєї відповіді, не вдаючись негайно до звинувачень у прихованих мотивах (капелюхи, справді ?!).
Кріс Даун

@ChrisDown Навпаки - я в ньому повністю для капелюхів. Також це було позначено як не відповідь кількох людей, але це віддалений другий пріоритет для капелюхів
Michael Mrozek

Другий з обмеженням пам’яті зробив трюк (для мого 1-рядкового файлу 2,5 Гб): спасибі! sedХоча трохи розчарований . : \
Томіслав Накіч-Альфіревич
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.