Mẫu thay thế trong một tệp có nội dung của tệp khác


20

Tôi có một tệp văn bản ( devel.xml).

Tôi đã thêm từ REPLACETHIS vào nó để thay thế chuỗi này bằng nội dung trong một tệp khác ( temp.txt).

Thứ gần nhất tôi có là đây:

sed -i -e "/REPLACETHIS/r temp.TXT" -e "s///" devel.txt;

Điều này chèn nội dung sau chuỗi, và sau đó xóa chuỗi sau đó.

Đây có phải là cách tốt nhất để làm điều đó?


Nó có phải là sed? Tùy thuộc vào số lượng văn bản trong temp.txt, tôi có thể đẩy mạnh giải pháp perl.
dùng17591

Câu trả lời:


34

Những gì bạn đã làm là xóa SUBSTITUTETHISbất cứ nơi nào nó xuất hiện trong tệp (nhưng không phải phần còn lại của dòng nơi nó xuất hiện) và chèn nội dung temp.TXTbên dưới dòng đó. Nếu SUBSTITUTETHISxuất hiện nhiều lần trên một dòng, chỉ có lần xuất hiện đầu tiên được xóa và chỉ một bản sao temp.TXTđược thêm vào.

Nếu bạn muốn thay thế toàn bộ dòng khi SUBSTITUTETHISxuất hiện, sử dụng dlệnh. Vì bạn cần chạy cả hai rdkhi có trận đấu, hãy xếp chúng vào một nhóm giằng.

sed -e '/SUBSTITUTETHIS/ {' -e 'r temp.TXT' -e 'd' -e '}' -i devel.txt

Một số triển khai sed cho phép bạn sử dụng dấu chấm phẩy để phân tách các lệnh và bỏ qua các dấu phân cách hoàn toàn xung quanh dấu ngoặc, nhưng bạn vẫn cần một dòng mới để chấm dứt đối số cho rlệnh:

sed -e '/SUBSTITUTETHIS/ {r temp.TXT
                          d}' -i devel.txt

Nếu bạn muốn thay thế SUBSTITUTETHISbằng nội dung của tệp, nhưng giữ lại những gì đến trước và sau nó trên dòng, thì phức tạp hơn. Phương pháp đơn giản nhất là bao gồm nội dung của tệp trong lệnh sed; lưu ý rằng bạn sẽ phải trích dẫn chính xác nội dung của nó.

sed -e "s/SUBSTITUTETHIS/$(<temp.TXT sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' | tr -d '\n')/g" -i devel.txt

Hoặc sử dụng Perl. Đây là ngắn nhưng chạy catmột lần cho mỗi thay thế:

perl -pe 's/SUBSTITUTETHIS/`cat temp.TXT`/ge' -i devel.txt

Để đọc tệp một lần khi tập lệnh bắt đầu và tránh phụ thuộc vào lệnh shell:

perl -MFile::Slurp -pe 'BEGIN {$r = read_file("temp.TXT"); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

(được trình bày trên hai dòng để dễ đọc nhưng bạn có thể bỏ qua ngắt dòng). Nếu tên tệp là biến, để tránh trích dẫn các vấn đề, hãy chuyển nó đến tập lệnh thông qua biến môi trường:

replacement_file=temp.TXT perl -MFile::Slurp -pe 'BEGIN {$r = read_file($replacement_file); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

Làm thế nào tôi có thể thay đổi lệnh perl để thay vì cat temp.txttôi có thể làm được cat ${variable}?
Maria Ines Parniari

@MariaInesParnisari Tôi đã mắc lỗi với định dạng nhận xét. Xem câu trả lời của tôi, với một giải pháp hơi khác, mạnh mẽ hơn.
Gilles 'SO- ngừng trở nên xấu xa'

Vì File :: Slurp không phải lúc nào cũng được cài đặt, nên một cách khác là sử dụng công -0777tắc để ẩn trong toàn bộ tệp và thông thường open:perl -0777 -pe 'BEGIN {open F, q(temp.TXT); $r=<F>; chomp($r)} s/SUBSTITUTETHIS/$r/ge' -i devel.txt
mivk

Cách gói r temp.TXTbằng các tin nhắn như "BEGIN temp.TXT", "END temp.TXX"
kyb

Tôi tìm thấy giải pháp cho câu hỏi của tôi. Sử dụng alệnh (thêm). grymoire.com/Unix/Sed.html#uh-36
kyb
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.