Perintah sed dasar pada file satu baris besar: tidak dapat mengalokasikan kembali memori

10

Saya memiliki file teks 250 MB, semuanya dalam satu baris.

Dalam file ini saya ingin mengganti akarakter dengan bkarakter:

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

Gagal dengan:

sed: couldn't re-allocate memory

Tampak bagi saya bahwa tugas semacam ini dapat dilakukan inline tanpa mengalokasikan banyak memori.
Apakah ada alat yang lebih baik untuk pekerjaan itu, atau cara yang lebih baik untuk digunakan sed?


GNU sed versi 4.2.1
Ubuntu 12.04.2 LTS
1 GB RAM

Nicolas Raoul
sumber
4
Pertanyaan itu adalah tentang ekspresi multiline yang sangat kompleks. Pertanyaan saya adalah tentang ekspresi paling dasar yang dapat Anda bayangkan.
Nicolas Raoul
@RubanSavvy plus, tak satu pun dari jawaban di Q lain memperhitungkan garis panjang dan pada kenyataannya, keduanya mungkin akan memiliki masalah yang sama.
terdon
Bisakah Anda memasukkan versi sed Anda dalam Q ini dan juga info perangkat keras Anda (RAM khusus) dan versi distro?
slm

Jawaban:

10

Ya, gunakan trsaja:

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

sedberurusan dalam garis sehingga garis besar akan menyebabkan masalah. Saya berharap itu mendeklarasikan variabel internal untuk menahan garis dan input Anda melebihi ukuran maksimum yang dialokasikan untuk variabel itu.

tr di sisi lain berurusan dengan karakter dan harus dapat menangani garis panjang yang sewenang-wenang dengan benar.

terdon
sumber
Anehnya saya baru saja membuat file 250MB diisi dengan "abcabc ..." dan dapat melakukannya sed -e "s/a/z/g" b.txt > c.txttanpa masalah. Menggunakan sed (GNU sed) 4.2.2.
slm
ss @ sama di sini pada file 496M dan sedversi yang sama , kira itu tergantung pada implementasi atau perangkat keras.
terdon
Ya jika saya harus menebak kita berurusan dengan versi yang lebih lama sed.
slm
5

Versi historis sed dan awk memiliki masalah memori, ini sebagian besar telah diperbaiki di versi yang lebih baru, tetapi salah satu kejadian klasik dari masalah ini mengenai Larry Wall cukup keras. jawabannya adalah menulis bahasa pemrograman baru - tanpa batas memori selain perangkat keras. Dia menyebutnya perl. masalah spesifik Anda dapat diselesaikan lebih sederhana, tetapi aturan umum yang saya gunakan adalah ketika sed tidak akan menggunakan perl.

Edit: dengan meminta contoh:

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

atau untuk penggunaan memori lebih sedikit:

perl -e 'BEGIN{$/=\32768}' -pe "s/a/b/g" < one-line-250-mb.txt
Hildred
sumber
1
Seluruh paragraf ini bermuara pada "Perl." Beberapa perincian akan menyenangkan, atau setidaknya contoh atau sesuatu
Michael Mrozek
@MichaelMrozek Saya menyadari bahwa koleksi topi cenderung mengarah ke roboediting, tapi saya pikir dengan reputasi Anda, Anda akan membayar sedikit perhatian lebih dekat. Khususnya dalam hal masalah khusus telah diselesaikan, dengan cara yang sangat sempit, yang tidak akan membantu mayoritas orang mencari, jadi saya menambahkan jawaban untuk kasus umum. jawaban diperluas yang saya berikan akan membantu Nicolas Raoul Jika belum ada solusi yang bisa diterapkan, tetapi saya ragu itu akan membantu banyak orang lain, sedangkan jawaban asli saya akan membantu semua orang yang mencapai batas sed. Jika Anda tidak setuju, saya akan menghapus
hildred
@hildred Saya tidak berpikir itu terlalu banyak untuk bertanya bahwa Anda dapat menganggap itikad baik dari moderator ketika mereka membuat komentar yang valid pada jawaban Anda, tanpa segera beralih ke tuduhan motif tersembunyi (topi, sungguh ?!).
Chris Down
@ ChrisDown Sebaliknya - saya di dalamnya sepenuhnya untuk topi. Juga ini ditandai sebagai bukan jawaban oleh banyak orang, tetapi itu adalah prioritas kedua yang jauh dari topi
Michael Mrozek
Yang kedua dengan keterbatasan memori melakukan trik (untuk file 1-line 2.5GB saya): terima kasih! Agak kecewa dengan sed, meskipun. : \
Tomislav Nakic-Alfirevic