Thay thế chuỗi đa dòng trong các tệp


17

Tôi có một số tệp tôi muốn cập nhật bằng cách thay thế một chuỗi nhiều dòng bằng một chuỗi nhiều dòng khác. Một cái gì đó dọc theo dòng:

* Some text, 
* something else
* another thing

Và tôi muốn thay thế nó bằng:

* This is completely
* different text

Kết quả sẽ là sau khi thay thế tệp chứa khối văn bản đầu tiên, bây giờ sẽ chứa chuỗi thứ hai (phần còn lại của tệp không thay đổi).

Một phần của vấn đề là tôi phải tìm danh sách các tệp sẽ được cập nhật trong hệ thống tệp. Tôi đoán rằng tôi có thể sử dụng grep cho điều đó (mặc dù một lần nữa điều đó không dễ thực hiện với chuỗi đa dòng) sau đó có thể đặt nó trong sed?

Có cách nào làm dễ hơn không? Sed là một tùy chọn nhưng thật bất tiện vì tôi phải thêm \ n, v.v ... Có cách nào để nói "lấy đầu vào từ tệp này, khớp nó trong các tệp đó, sau đó thay thế bằng nội dung của tệp khác này" không? Tôi có thể sử dụng python nếu cần, nhưng tôi muốn một cái gì đó nhanh chóng và đơn giản, vì vậy nếu có sẵn một tiện ích, tôi thà sử dụng nó hơn là viết kịch bản của riêng tôi (mà tôi biết cách làm).


Bạn có lẽ nên sử dụng perl cho việc này. stackoverflow.com/questions/1030787/ trộm
orion

3
Vì vậy, bạn muốn phù hợp some text, something else another thingcho dù nó có kéo dài nhiều dòng? Hay bạn chỉ muốn khớp some text,\nsomething else\nanotherthing?
mikeerv

2
Chỉnh sửa câu hỏi của bạn và làm rõ chính xác nội dung của từng tệp là gì và đầu ra mong muốn là gì.
jimmij

Chuỗi kéo dài nhiều dòng. Tôi khá coi thường khoảng trắng khi khớp / thay thế bởi vì nó có thể không hoàn toàn giống nhau, nhưng nó không phải là vấn đề lớn nếu tôi chỉ thực hiện trận đấu 1-1 (dòng mới và tất cả).
ventsyv

Câu trả lời:


12

Thay thế "Một số ... \ n ... Điều" bằng nội dung của tệp "mới" trong một hoặc nhiều tệp đầu vào

perl -i -p0e 's/Some.*?thing\n/`cat new`/se' input.txt ...
  1. -i để thay đổi trực tiếp input.txt
  2. -p0 slurp tập tin đầu vào và in nó vào cuối
  3. s/regexp/.../s trong regrec ..|\n
  4. s/.../exp/e thay thế bởi eval(exp)
  5. mới - một tệp chứa văn bản thay thế (Đây hoàn toàn là ... văn bản khác)
  6. nếu hữu ích bạn có thể mở rộng văn bản gốc s/Some text\n...\n...thing\n/...

Làm thế nào tôi có thể làm tương tự với một tệp có tên là "trước" để tìm nội dung (nhiều dòng) của tệp đó? Tôi đã thử nhưng nó không hoạt động.
Kvothe

@Kvothe, chúng tôi cần thêm chi tiết ... Giả sử rằng "trước đây" không có ký tự đặc biệt, bạn có thể thửperl -i -p0e ' $b= `cat before`; s/$b/Some thing\n/se' input.txt ...
JJoao

Và giả sử "trước" chứa tất cả các ký tự đặc biệt (dòng mới, dấu gạch chéo, dấu ngoặc) ngoại trừ 'và `.
Kvothe

5
sed -e :n -e '$!N;/\n.*\n/!{$!bn
};  s/some text,\n* *something else\n* *another thing/this is completely\
different text/;P;D' <infile

Tôi sợ rằng bạn sẽ có một thời gian khó khăn để đưa ra một giải pháp phù hợp với bạn cho đến khi bạn đưa ra một mô tả cụ thể về vấn đề - nhưng đó là những gì QA phù hợp nhất, như tôi thấy. Có thể điều này sẽ cho bạn một ý tưởng - nó sẽ luôn giữ 3 dòng trong không gian mẫu cùng một lúc - với giao diện 2 dòng - trong khi trượt về phía trước qua tệp đầu vào chỉ một dòng.

Nó có thể phù hợp với chuỗi của bạn cho dù nó có kéo dài nhiều dòng hay không - tối đa là ba. Nhưng không có quy định nào phản ánh điều khoản đó trong sự thay thế - nó luôn kéo dài hai dòng như văn bản.


0

Không mạnh mẽ (vì không chọn chuỗi thứ hai nhưng dễ giải quyết) và có thể không phải là trình biên dịch posix nhưng rất đơn giản:

sed '/^Some text/{:1;/another thing$/!{N;b 1}
     s/.*/this is completely\ndifferent text/g}' input.txt

Lệnh đầu tiên thêm dòng từ Một số văn bản cho đến khi đã gặp một điều khác sau đó dòng thứ hai thay đổi nó thành văn bản khác.

LƯU Ý Hạn chế là một số văn bản phải luôn được theo sau bởi một điều khác .


Vấn đề là chuỗi có thể có nhiều hơn 2 dòng (tối đa một chục hoặc hơn) và có thể chứa các nội dung khác có thể cần phải thoát, chẳng hạn như các tab, * vv
ventsyv

@ventsyv Không có vấn đề gì với số lượng dòng hoặc dấu phân cách - tập lệnh chỉ kiểm tra điểm bắt đầu và kết thúc. Nó là khá đủ NẾU chuỗi bắt đầu một cách khéo léo có thể đánh dấu văn bản để thay đổi . Nếu không có tốt hơn của bạn hiển thị ví dụ đầu vào để tạo ra mẫu chính xác.
Costas
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.