Menghapus sebagian file teks dan mengikuti baris menggunakan sed

8

Saya perlu mengedit file seperti berikut:

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

tujuannya adalah untuk menghapus baris yang dimulai dengan 'iface ... inet6' dan juga menghapus beberapa yang dimulai dengan spasi (bisa tidak ada atau lebih dari satu):

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

dan jaga sisanya untuk hasil berikut:

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

Saya mencoba dengan sed menggunakan sebagai berikut:

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

tetapi menghapus semuanya mulai dari tempat yang tepat tetapi terhapus sampai akhir. Saya hanya ingin menghapus garis menatap spasi setelah teks iface pilih.

fcm
sumber
1
@ fcm beri tahu kami jika solusi di bawah ini ok. jika tidak, kami dapat mengubahnya untuk Anda
1
@TNT bukan pertanyaan yang sama. Ini BUKAN untuk menghapus satu baris, adalah menghapus satu baris plus baris berikut yang berhadapan dengan spasi.
fcm
2
Secara teoritis duplikat, tetapi tidak dalam praktiknya - saya pikir akan lebih baik untuk memberikan jawaban terpisah di sini yang menunjukkan cara mencocokkan dari pola yang diberikan melalui baris berikutnya yang memiliki spasi putih terkemuka.
Jeff Schaller
1
@rudic memberikan jawaban yang sangat bagus dan rumit yang jauh dari pencarian sederhana dan hapus, tidak ada pada dup yang disarankan mendekati itu.
fcm

Jawaban:

7

Coba adaptasi sedone liner Anda ini:

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

Ini cocok dengan rentang dari pola pertama Anda ke baris pertama TIDAK dimulai dengan spasi, dan menghapus garis dimulai dengan spasi atau "i" (untuk yang memimpin iface). Perlu memikirkan kembali harus idiminta setelah blok.

Sepertinya ini berfungsi:

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

Mohon coba dan laporkan kembali.

RudiC
sumber
6

Script untuk standar sedyang menggunakan loop eksplisit untuk menghapus baris:

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

Script menemukan inet6garis dan kemudian menambahkan baris berikutnya ke garis itu secara internal dalam ruang pola (dengan karakter baris baru yang disematkan di antara). Itu kemudian menghapus ruang pola hingga dan termasuk karakter baris baru pertama (ini menghapus inet6garis asli ). Ini terus melakukan ini sampai ruang pola tidak dimulai dengan karakter kosong (spasi atau tab).

Pengujian:

$ 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

Pengujian pada data buatan:

$ 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

Script sebagai "satu baris":

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

Anda sudah mendapatkan jawaban yang baik untuk sedalat, tetapi izinkan saya mengusulkan yang lain, saya percaya pendekatan yang lebih sederhana, menggunakan pcregrep:

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

Regex harus jelas - kami mencari pola mulai dari baris ^iface.*inet6dan kemudian kelompok karakter ATAU baris baru diikuti oleh spasi tunggal yang diulang nol atau lebih banyak kali. Maka kita hanya perlu menginstruksikan pcregrepuntuk memungkinkan pencocokan multi-linear dengan -Mopsi dan membalikkan semuanya dengan -v(bagian yang cocok akan dihapus).

jimmij
sumber
Saya biasanya lebih suka menggunakan pcregrep, jauh lebih intuitif.
Rui F Ribeiro