Thay thế nhiều dòng


8

Tôi đã dành nhiều năm cố gắng để tìm ra điều này. Khi nó xảy ra, tôi không cần phải làm điều đó nữa; Tôi tìm thấy một cách khác. Nhưng vì sự tỉnh táo của tôi, tôi vẫn muốn biết câu trả lời.

Nó khá dễ sử dụng sedđể thay thế một điểm đánh dấu bằng một số đoạn văn bản. Những gì tôi không thể tìm ra là làm thế nào để sedchèn một khối văn bản khổng lồ, với định dạng phức tạp như nhiều dòng, ký tự tab, v.v. Làm thế nào để bạn làm điều đó? Là sedthứ tốt nhất để sử dụng hay là gì?


1
Tôi thấy rằng python & regex linh hoạt hơn nhiều so với sed trong các thay thế đa dòng phức tạp.
Tombolinux

Câu trả lời:


3

Nếu bạn có văn bản được chèn tại (các) điểm đánh dấu trong tệp có tên /tmp/insert.txt, bạn có thể thực hiện tác vụ này như sau:

sed '/MARKER/ r /tmp/insert.txt' < inputfile

Lệnh sed ở trên sẽ đọc "inputfile" và tìm kiếm MARKER. Khi tìm thấy nó, nó sẽ chèn nội dung của /tmp/insert.txt vào luồng đầu ra.

Nếu bạn muốn xóa điểm đánh dấu, hãy thử điều này:

sed '/MARKER/ {s/MARKER//; r /tmp/insert.txt
}' <inputfile

Lưu ý dấu ngoặc đóng "}" phải được bắt đầu bằng một dòng mới.

Như trong lệnh đầu tiên, sed sẽ hoạt động trên các dòng với MARKER. Nó sẽ thay thế MarkER bằng không có gì, và sau đó nó sẽ đọc trong /tmp/insert.txt


3

Tôi sẽ sử dụng excho loại nhiệm vụ đó, trừ khi bạn thực sự có một luồng dữ liệu. Tôi sẽ giữ các exlệnh trong tài liệu ở đây:

ex $FILENAME << END_EX_COMMANDS
" Find the mark, assuming it's an entire line
/^MARKER$/
" Delete the marker line
d
" Add the complex, multi-line text
a
Complex, vividly formatted text here.
Even more "specially" formatted text.
.
" The '.' terminates the a-command. Write out changed file.
w!
q
END_EX_COMMANDS

Sử dụng exlà một lợi thế cho vihoặc vimngười dùng: họ đã biết tổ hợp phím cho các lệnh, mặc dù nó mang lại cho bạn cảm giác chỉnh sửa mù. Bạn cũng có thể thực hiện nhiều thay thế hoặc thay thế toàn cầu, bất cứ điều gì vimcó thể làm trong chế độ ':'.


2

Tôi tin rằng lệnh này là những gì bạn đang tìm kiếm:

r FILENAME
     As a GNU extension, this command accepts two addresses.

     Queue the contents of FILENAME to be read and inserted into the
     output stream at the end of the current cycle, or when the next
     input line is read.  Note that if FILENAME cannot be read, it is
     treated as if it were an empty file, without any error indication.

     As a GNU `sed' extension, the special value `/dev/stdin' is
     supported for the file name, which reads the contents of the
     standard input.

0

Đây là phiên bản đơn giản hóa câu trả lời của Bruce Ediger bằng cách sử dụng lệnh thay đổi , là sự kết hợp giữa xóa và chắp thêm.

ex $FILENAME << EOEX
/^MARKER$/c
The new text
to be inserted
here.
.
w!
q
EOEX

0

Nếu bạn muốn xóa điểm đánh dấu, hãy thử điều này trong một dòng:

sed -e '/MARKER/ r /tmp/insert.txt' -e '/MARKER/d' < inputfile

hoặc là

sed -e '/MARKER/ {r /tmp/insert.txt' -e 'd }' < inputfile
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.