Podstawowe polecenie sed dla dużego pliku jednowierszowego: nie można ponownie przydzielić pamięci

10

Mam plik tekstowy 250 MB, wszystko w jednym wierszu.

W tym pliku chcę zastąpić aznaki bznakami:

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

Nie działa z:

sed: couldn't re-allocate memory

Wydaje mi się, że tego rodzaju zadanie można wykonać w jednej linii bez przydzielania dużej ilości pamięci.
Czy istnieje lepsze narzędzie do pracy lub lepszy sposób użycia sed?


GNU sed wersja 4.2.1
Ubuntu 12.04.2 LTS
1 GB RAM

Nicolas Raoul
źródło
4
To pytanie dotyczy bardzo złożonego wyrażenia wieloliniowego. Moje pytanie dotyczy najbardziej podstawowego wyrażenia, jakie można sobie wyobrazić.
Nicolas Raoul,
@RubanSavvy plus, żadna z odpowiedzi na drugim Q nie bierze pod uwagę długiej linii i w rzeczywistości obie prawdopodobnie miałyby ten sam problem.
terdon
Czy możesz dołączyć swoją wersję sed do tego Q, a także informacje o sprzęcie (konkretnie RAM) i wersję dystrybucyjną?
slm

Odpowiedzi:

10

Tak, trzamiast tego użyj :

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

sedzajmuje się liniami, więc ogromna linia spowoduje problemy. Oczekuję, że wewnętrzne zadeklarowanie zmiennej utrzymuje linię, a dane wejściowe przekraczają maksymalny rozmiar przydzielony tej zmiennej.

tr z drugiej strony zajmuje się postaciami i powinien być w stanie poprawnie obsługiwać dowolnie długie linie.

terdon
źródło
Co ciekawe, właśnie utworzyłem plik 250 MB wypełniony w / „abcabc ...” i byłem w stanie poradzić sobie sed -e "s/a/z/g" b.txt > c.txtbez żadnych problemów. Korzystanie z sed (GNU sed) 4.2.2.
slm
@slm to samo tutaj na pliku 496M i tej samej sedwersji, zgadnij, że zależy to od implementacji lub sprzętu.
terdon
Tak, gdybym miał zgadywać, mamy do czynienia ze starszą wersją sed.
slm
5

Historyczne wersje sed i awk miały problemy z pamięcią, zostały one głównie naprawione w nowszych wersjach, ale jedno z klasycznych wystąpień tego problemu bardzo mocno uderzyło Larry'ego Walla . jego odpowiedzią było napisanie nowego języka programowania - bez ograniczeń pamięci innych niż sprzęt. Nazwał to perl. twój konkretny problem można rozwiązać prościej, ale ogólną zasadą, której używam, jest to, że sed nie używa perla.

Edytuj: poproś o przykład:

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

lub mniejsze zużycie pamięci:

perl -e 'BEGIN{$/=\32768}' -pe "s/a/b/g" < one-line-250-mb.txt
Hildred
źródło
1
Cały akapit sprowadza się do „Perla”. Przydałyby się jakieś szczegóły, a przynajmniej przykład czy coś takiego
Michał Mrożek
@MichaelMrozek Zdaję sobie sprawę, że kolekcja czapek często prowadzi do roboeditingu, ale pomyślałem, że z twoją reputacją zwrócisz trochę większą uwagę. W szczególności, ponieważ konkretny problem został już rozwiązany, w bardzo wąski sposób, co nie pomogłoby większości osób poszukujących, więc dodałem odpowiedź na ogólny przypadek. udzielona przeze mnie rozszerzona odpowiedź pomogłaby Nicolasowi Raoulowi, gdyby nie było jeszcze wykonalnego rozwiązania, ale wątpię, by pomogło wielu innym, podczas gdy moja oryginalna odpowiedź pomogłaby każdemu, kto osiągnął granice sed. Jeśli się nie zgadzasz,
skreślę
@hildred Nie sądzę, aby zbytnio prosić, abyś mógł założyć dobrą wiarę moderatorów, którzy robią ważne komentarze na temat twojej odpowiedzi, bez uciekania się natychmiast do oskarżeń o ukryte motywy (kapelusze, naprawdę ?!).
Chris Down,
@ChrisDown Przeciwnie - jestem w tym całkowicie za czapkami. Również wiele osób oznaczyło to jako odpowiedź, ale jest to odległy drugi priorytet kapeluszy
Michael Mrozek
Drugi z ograniczeniem pamięci załatwił sprawę (dla mojego 1-liniowego pliku 2,5 GB): dzięki! Trochę rozczarowany sed. : \
Tomislav Nakic-Alfirevic,