Thay thế chuỗi bằng nội dung của tệp bằng sed


23

Tôi có hai tệp khác nhau:

Tệp1

/home/user1/  
/home/user2/bin  
/home/user1/a/b/c

Tệp2

<TEXT1>
<TEXT2>

Tôi muốn thay thế <TEXT1>của File2 với các nội dung của File1 sử dụng sed. Tôi đã thử lệnh này, nhưng không nhận được đầu ra thích hợp:

cat File2|sed "s/<TEXT1>/$(cat File1|sed 's/\//\\\//g'|sed 's/$/\\n/g'|tr -d "\n")/g"

Bạn có thể sử dụng các công cụ khác cũng để giải quyết vấn đề này.


Vui lòng dán thông báo lỗi đó để chúng tôi có thể xác định vị trí nguồn của nó. Cũng cho chúng tôi biết sedbạn đang sử dụng triển khai nào. Mã của bạn hoạt động với tôi với GNU sed.
manatwork

Xin lỗi, không nhận được một lỗi. Tôi không nhận được đầu ra mong muốn. Đầu ra là như thế /home/user1/ n/home/user2/bin n/home/user1/a/b/cn <TEXT2>. Không nhận được dòng mới.
chanchal1987

Không chắc chắn nếu điều này sẽ áp dụng trong trường hợp cụ thể của bạn, nhưng với diffpatchcác công cụ cho phép thay thế một số dòng trong một tệp bằng các dòng khác khá dễ dàng.
Stéphane Gimenez

1
Btw, sử dụng dữ liệu ngẫu nhiên được thu thập $()trong một tập lệnh sed khiến mắt tôi chảy máu. Không bao giờ sử dụng dữ liệu ngoài ở những nơi mà một số ký tự được diễn giải với ý nghĩa đặc biệt.
Stéphane Gimenez

Câu trả lời:


24

Đây là một giải pháp kịch bản sed (dễ nhìn hơn là cố gắng đưa nó vào một dòng trên dòng lệnh):

/<TEXT1>/ {
  r File1
  d
}

Chạy nó:

$ sed -f script.sed File2
/home/user1/
/home/user2/bin
/home/user1/a/b/c
<TEXT2>

Cảm ơn điều này đang làm việc. Nhưng tôi không muốn sử dụng bất kỳ tập tin kịch bản nào khác. Có bất kỳ giải pháp nội tuyến?
chanchal1987

Chắc chắn : sed '/<TEXT1>/{rFile1^Md^M}' File2, trong đó "^ M" là bạn nhấn return. Vấn đề là sed thực sự cần các dòng mới trong {...} để phân định lệnh r và lệnh d.
Kusalananda

6
với bash, chuỗi kiểu posix sạch hơn một chút:sed $'/<TEXT1>/ {r File1\n d}'
glenn jackman

9
Ngoài ra với -e cho một lớp lót:sed -e '/<TEXT1>/{r File1' -e 'd}' File2
sdaau

1
Và nếu thay vì thay thế toàn bộ dòng chứa <TEXT1>, tôi chỉ muốn thay thế chính chuỗi đó, giữ nguyên phần còn lại của dòng thì sao? Text1: <TEXT1>để Text1: <file_contents>.
Robin Winslow

9

Mất một thời gian dài để tìm giải pháp này bằng cách sử dụng thay thế var. Tất cả các giải pháp sed không hoạt động với tôi, vì chúng sẽ xóa các dòng hoàn chỉnh hoặc thay thế không chính xác.

FILE2=$(<file2)
FILE1=$(<file1)
echo "${FILE2//TEXT1/$FILE1}" 

Thay thế tất cả các lần xuất hiện của TEXT1 trong tệp2 bằng nội dung của tệp1. Tất cả các văn bản khác vẫn còn nguyên.


rất đẹp. có thể nhanh hơn sedquá, vì những "mở rộng" đó (còn gọi là thay thế) được tích hợp vào vỏ ( bashít nhất là)
màu vàng êm dịu

7

Tôi trả lời vì phương thức diff/ patchcó thể được quan tâm trong một số trường hợp. Để xác định thay thế các dòng có trong tệp blob1bằng các dòng có trong blob2sử dụng:

diff -u blob1 blob2 > patch-file

Ví dụ: nếu blob1chứa:

hello
you

blob2chứa:

be
welcome
here

tạo ra patch-filesẽ là:

--- blob1   2011-09-08 16:42:24.000000000 +0200
+++ blob2   2011-09-08 16:50:48.000000000 +0200
@@ -1,2 +1,3 @@
-hello
-you
+be
+welcome
+here

Bây giờ, bạn có thể áp dụng bản vá này cho bất kỳ tệp nào khác:

patch somefile patch-file

Nó sẽ thay thế hello, youdòng bằng be, welcome, heredòng trong somefile.


điều này thực sự thông minh nhưng sẽ tốt hơn nếu bạn có thể tự động hóa nó trong một kịch bản
qodeninja
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.