Xóa một phần của tệp văn bản và các dòng sau bằng sed


8

Tôi cần chỉnh sửa một tập tin như sau:

auto wlx00
allow-hotplug wlx00
iface wlx000 inet dhcp
iface wlx000 inet6 auto
  post-up sysctl -w net.ipv6.conf.wlx000.accept_ra=2
auto wlx000

mục tiêu là xóa các dòng bắt đầu bằng 'iface ... inet6' và cũng xóa một số dòng tiếp theo bắt đầu bằng dấu cách (có thể không có hoặc nhiều hơn một):

iface wlx000 inet6 auto
  post-up sysctl -w net.ipv6.conf.wlx000.accept_ra=2

và giữ phần còn lại nguyên vẹn cho kết quả sau:

auto wlx00
allow-hotplug wlx00
iface wlx000 inet dhcp
auto wlx000

Tôi đã thử với sed sử dụng như sau:

sed -i.old -r -e "/iface\s*\w*\s*inet6.*/,\${d;/^\s.*/d;}" /etc/configfile

nhưng nó loại bỏ mọi thứ bắt đầu ở đúng nơi nhưng xóa dần đến cuối cùng. Tôi chỉ muốn loại bỏ các dòng nhìn chằm chằm vào không gian sau văn bản iface chọn.


1
@fcm vui lòng cho chúng tôi biết nếu các giải pháp dưới đây là ok. nếu không, chúng tôi có thể điều chỉnh nó cho bạn


1
@TNT không cùng câu hỏi. Điều này KHÔNG phải để xóa một dòng, là xóa một dòng cộng với các dòng sau nhìn chằm chằm vào không gian.
fcm

2
Về mặt lý thuyết là một bản sao, nhưng không thực tế - tôi nghĩ sẽ tốt hơn nếu cung cấp một câu trả lời riêng ở đây để giải thích cách khớp từ một mẫu nhất định thông qua các dòng tiếp theo có khoảng trắng hàng đầu.
Jeff Schaller

1
@rudic cung cấp một câu trả lời xuất sắc và công phu khác xa với việc tìm kiếm và xóa đơn giản, không có gì trên bản sao được đề xuất gần đó.
fcm

Câu trả lời:


7

Hãy thử sự thích ứng này của sedmột lớp lót của bạn :

sed  '/iface\s*\w*\s*inet6.*/,/^[^ ]/ {/^[^ i]/!d}' file

Nó phù hợp với phạm vi từ mẫu đầu tiên của bạn đến dòng đầu tiên KHÔNG bắt đầu bằng char không gian và xóa các dòng bắt đầu bằng khoảng trắng hoặc "i" (đối với hàng đầu iface). Cần suy nghĩ lại nên iđược yêu cầu sau khi khối.

Có vẻ như điều này hoạt động:

sed -n '/iface\s*\w*\s*inet6.*/ {:L; n; /^[ ]/bL;}; p' file

Xin hãy thử và báo cáo lại.


6

Một tập lệnh cho tiêu chuẩn sedsử dụng một vòng lặp rõ ràng để xóa các dòng:

/^iface .* inet6/ {
    :again
    N
    s/.*\n//
    /^[[:blank:]]/b again
}

Kịch bản tìm các inet6dòng và sau đó nối thêm dòng tiếp theo vào dòng đó trong không gian mẫu (với một ký tự dòng mới được nhúng ở giữa). Sau đó, nó sẽ xóa không gian mẫu lên đến và bao gồm ký tự dòng mới đầu tiên (cái này sẽ xóa inet6dòng gốc ). Nó tiếp tục làm điều này cho đến khi không gian mẫu không bắt đầu bằng một ký tự trống (khoảng trắng hoặc tab).

Kiểm tra:

$ cat file
auto wlx00
allow-hotplug wlx00
iface wlx000 inet dhcp
iface wlx000 inet6 auto
  post-up sysctl -w net.ipv6.conf.wlx000.accept_ra=2
auto wlx000
$ sed -f script.sed <file
auto wlx00
allow-hotplug wlx00
iface wlx000 inet dhcp
auto wlx000

Kiểm tra dữ liệu nhân tạo:

$ cat file
something1
something2
iface have a inet6 here
   delete me
   me too
   same here
something3
something4
iface more something inet6
   be gone
   skip this
something5
$ sed -f script.sed <file
something1
something2
something3
something4
something5

Kịch bản dưới dạng "một lớp lót":

sed -e '/^iface .* inet6/ {' -e ':a' -e 'N;s/.*\n//;/^[[:blank:]]/ba' -e '}'

3

Bạn đã có câu trả lời tốt cho sedcông cụ, nhưng hãy để tôi đề xuất cách khác, tôi tin rằng cách tiếp cận đơn giản hơn nhiều pcregrep:

pcregrep -Mv '^iface.*inet6(.|\n )*' file

Regex nên tự giải thích - chúng tôi tìm kiếm mẫu bắt đầu từ dòng ^iface.*inet6và sau đó nhóm bất kỳ ký tự nào HOẶC dòng mới theo sau là khoảng trắng lặp lại từ 0 lần trở lên. Sau đó, chúng ta chỉ cần hướng dẫn pcregrepcho phép kết hợp đa tuyến tính với -Mtùy chọn và đảo ngược toàn bộ mọi thứ bằng cách -v(phần phù hợp sẽ bị xóa).


Tôi thường thích sử dụng pcregrep, trực quan hơn nhiều.
Rui F Ribeiro
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.