Nhiều hành động tìm kiếm và thay thế trong một tệp văn bản lớn


11

Tôi có một tệp văn bản lớn (khoảng 2GB). Tôi muốn thực hiện năm hành động tìm kiếm và thay thế trên cùng một tệp và muốn thực hiện điều này trong một lệnh. Thông thường tôi sử dụng vim, mở tệp, thực hiện một hành động thay thế, sau đó tiếp theo, v.v. Có một lưu ý, như tôi nhận thấy rằng sau ba hoặc bốn lần tìm kiếm vim gặp sự cố vì vấn đề bộ nhớ.

Đây là hai ví dụ về lệnh tôi sử dụng trong Vim:

:%s/www\.abcdef/www.test.abcdef/g 
:%s/www\.klmnop/www.test.klmnop/g

cách tốt nhất để xử lý này là gì?

Câu trả lời:


8

Tôi sẽ sử dụng sed như thế này:

sed -i "s/www\.abcdef/www.test.abcdef/g;s/www\.kmlnop/www.test.klmnop/g;" yourfile.txt

-itùy chọn là viết tắt của thay thế "tại chỗ". Bạn có thể yêu cầu sed tạo bản sao lưu tệp của bạn cung cấp tiện ích mở rộng cho tùy chọn này ( -i.baksẽ sao lưu yourfile.txt dưới dạng yourfile.txt.bak).


Nhanh thật! Không chỉ câu trả lời của bạn ;-) mà tập lệnh này với 5 tìm kiếm và thay thế nhanh hơn khoảng 10 lần khi chỉ mở tệp trong vim. Một điều làm tôi bối rối mặc dù. Lúc đầu, tôi nghĩ tệp .bak sẽ là tệp được chỉnh sửa, nhưng tất nhiên nó là bản gốc.
XUÂN NGÀY 11/07/13

Mười hành động tìm kiếm và thay thế (với hàng ngàn lượt truy cập) trong một tệp 2 GB trong một lần, không có vấn đề về bộ nhớ. Chưa đến hai phút trên một máy tính để bàn trung bình - siêu!
XUÂN NGÀY 11/07/13

Một câu hỏi ... Bạn thoát khỏi các dấu chấm trong chuỗi thay thế. Điều này có cần thiết không?
XUÂN NGÀY 11/07/13

1
Bạn được chào đón @rxt :) Trên thực tế, bạn đúng, bạn có thể sử dụng các dấu chấm không thoát trong chuỗi thay thế trong sed. Tôi đã thử, và nó hoạt động. Có một chủ đề tốt trong Unix & Linux Stackexchange và câu trả lời được chấp nhận không đề cập đến các dấu chấm như các ký tự để thoát.
ssssteffff

2
@rxt bạn nói thay thế chuỗi, xin lỗi, không bạn không cần phải thoát chúng ở đó.
terdon

6

Nếu bạn có nhiều mẫu tìm kiếm hơn, bạn có thể lưu chúng trong một tệp và đọc các thay thế từ đó. Ví dụ: giả sử đây là nội dung của replacements.txt:

www\.abcdef www.test.abcdef 
www\.klmnop www.test.klmnop

Sau đó, bạn có thể đọc danh sách N thay thế và thay thế chúng bằng:

while read from to; do
  sed -i "s/$from/$to/" infile.txt ; 
done < replacements.txt 

GHI CHÚ:

  • Điều này giả định rằng chuỗi tìm kiếm của bạn không chứa khoảng trắng và bất kỳ ký tự lạ nào cần được thoát vào replacements.txt.
  • Nó sẽ chạy một cái sedcho mỗi lần thay thế có thể mất một lúc nếu bạn có nhiều thao tác thay thế.
  • Nó có thể xử lý một số lượng thay thế tùy ý (hàng ngàn hoặc hàng triệu hoặc bất cứ điều gì) miễn là bạn không bận tâm rằng sẽ mất thêm một chút thời gian.

Một lựa chọn khác là viết phần trên dưới dạng sedtập lệnh:

s/www\.abcdef/www\.test\.abcdef/g;
s/www\.kmlnop/www\.test\.klmnop/g;
s/aaaa/bbbb/g;
s/cccc/dddd/g;
s/eeee/ffff/g;

Sau đó, bạn có thể chạy tập lệnh trên tệp của mình và nó sẽ thực hiện tất cả các thay thế trong một lần:

sed -f replace.sed infile.txt 

+1 cho ,, tùy chọn khác ''. Có thể có ích để có các thay thế được lưu trữ trong một tập tin! (Tôi hy vọng tôi sẽ nhớ điều đó ...)
mpy

+1 cho "tùy chọn khác" cũng bởi vì nó sử dụng chức năng riêng thay vì tập lệnh tùy chỉnh, do đó dễ mang theo / dễ chia sẻ hơn
David Cook

@DavidCook cảm ơn, nhưng nó không có nguồn gốc hoặc di động hơn các loại khác. Cách tiếp cận đầu tiên là sử dụng vòng lặp POSIX, nó chính xác là di động như cách thứ hai. Nó sẽ chỉ chậm hơn nhiều vì nó sử dụng một vòng lặp shell.
terdon

Bạn nói đúng, ý tôi là định dạng tệp sed script dễ mang theo hơn, bởi vì nó sử dụng chức năng sed dựng sẵn thay vì tập lệnh, sẽ phải được chia sẻ cùng với tệp replacements.txt. Tuy nhiên, cả hai đều là lựa chọn tuyệt vời!
David Cook
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.