Lệnh sed cơ bản trên tệp một dòng lớn: không thể phân bổ lại bộ nhớ


10

Tôi có một tệp văn bản 250 MB, tất cả trong một dòng.

Trong tập tin này tôi muốn thay thế các aký tự bằng các bký tự:

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

Nó thất bại với:

sed: couldn't re-allocate memory

Dường như với tôi rằng loại nhiệm vụ này có thể được thực hiện nội tuyến mà không cần phân bổ nhiều bộ nhớ.
Có một công cụ tốt hơn cho công việc, hoặc một cách tốt hơn để sử dụng sed?


GNU sed phiên bản 4.2.1
Ubuntu 12.04.2
RAM 1 GB RAM



4
Câu hỏi đó là về một biểu hiện đa dòng rất phức tạp. Câu hỏi của tôi là về biểu thức cơ bản nhất bạn có thể tưởng tượng.
Nicolas Raoul

@RubanSavvy plus, cả hai câu trả lời trên Q kia đều không tính đến dòng dài và trên thực tế, cả hai có thể sẽ có cùng một vấn đề.
terdon

Bạn có thể bao gồm phiên bản sed của bạn trong Q này và cả thông tin phần cứng của bạn (cụ thể là RAM) và phiên bản phân phối không?
slm

Câu trả lời:


10

Có, sử dụng trthay thế:

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

sedgiao dịch trong các dòng vì vậy một dòng lớn sẽ gây ra vấn đề. Tôi hy vọng nó đang khai báo một biến trong nội bộ để giữ dòng và đầu vào của bạn vượt quá kích thước tối đa được phân bổ cho biến đó.

tr mặt khác xử lý các ký tự và có thể xử lý các dòng dài tùy ý một cách chính xác.


Thật kỳ lạ, tôi vừa tạo một tệp 250 MB chứa đầy w / "abcabc ..." và có thể thực hiện sed -e "s/a/z/g" b.txt > c.txtmà không gặp vấn đề gì. Sử dụng sed (GNU sed) 4.2.2.
slm

@slm giống nhau ở đây trên một tệp 496M và cùng một sedphiên bản, đoán nó phụ thuộc vào việc triển khai hoặc phần cứng.
terdon

Vâng, nếu tôi phải đi lang thang đoán chúng ta đang đối phó với một phiên bản cũ hơn sed.
slm

5

Các phiên bản lịch sử của sed và awk có vấn đề về bộ nhớ, chúng hầu hết đã được sửa trong các phiên bản gần đây, nhưng một trong những sự cố kinh điển của vấn đề này đã khiến Larry Wall gặp khó khăn. Câu trả lời của ông là viết một ngôn ngữ lập trình mới - không có giới hạn bộ nhớ nào ngoài phần cứng. Ông gọi nó là perl. vấn đề cụ thể của bạn có thể được giải quyết đơn giản hơn, nhưng nguyên tắc chung mà tôi sử dụng là khi sed sẽ không sử dụng perl.

Chỉnh sửa: bằng cách yêu cầu một ví dụ:

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

hoặc để sử dụng ít bộ nhớ hơn:

perl -e 'BEGIN{$/=\32768}' -pe "s/a/b/g" < one-line-250-mb.txt

1
Toàn bộ đoạn này sôi sùng sục thành "Perl.". Một số chi tiết sẽ rất hay, hoặc ít nhất là một ví dụ hoặc một cái gì đó
Michael Mrozek

@MichaelMrozek Tôi nhận ra rằng bộ sưu tập mũ có xu hướng dẫn đến việc đi lang thang, nhưng tôi nghĩ rằng với danh tiếng của bạn, bạn sẽ chú ý hơn một chút. Cụ thể ở chỗ, vấn đề cụ thể đã được giải quyết, theo một cách rất hẹp, điều đó sẽ không giúp được phần lớn mọi người tìm kiếm, vì vậy tôi đã thêm một câu trả lời cho trường hợp chung. câu trả lời mở rộng mà tôi cung cấp sẽ giúp Nicolas Raoul Nếu chưa có giải pháp khả thi, nhưng tôi nghi ngờ Nó sẽ giúp được rất nhiều người khác, trong khi câu trả lời ban đầu của tôi sẽ giúp mọi người đạt đến giới hạn của sed. Nếu bạn không đồng ý tôi sẽ xóa
hildred 19/12/13

@hildred Tôi không nghĩ rằng quá nhiều để hỏi rằng bạn có thể tin tưởng vào người điều hành khi họ đưa ra nhận xét hợp lệ cho câu trả lời của bạn, mà không cần phải ngay lập tức buộc tội những động cơ thầm kín (mũ, thực sự?!).
Chris Xuống

@ChrisDown Ngược lại - Tôi hoàn toàn dành cho những chiếc mũ. Ngoài ra, điều này được đánh dấu là không phải là câu trả lời của nhiều người, nhưng đó là ưu tiên thứ hai xa vời đối với những chiếc mũ
Michael Mrozek

Cái thứ hai với giới hạn bộ nhớ đã thực hiện thủ thuật (đối với tệp 1 dòng 2,5 GB của tôi): cảm ơn! Bit thất vọng bởi sed, mặc dù. : \
Tomislav Nakic-Alfirevic
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.