Cetak garis antara (dan tidak termasuk) dua pola


13

Saya akan mengirimkan formulir menggunakan cURL, di mana beberapa konten berasal dari file lain, dipilih menggunakan sed

Jika param1pola pencocokan baris dari file lain menggunakan sed, perintah di bawah ini akan berfungsi dengan baik:

curl -d param1="$(sed -n '/matchpattern/p' file.txt)" -d param2=value2 http://example.com/submit

Sekarang, pergilah ke masalah. Saya ingin hanya menampilkan teks di antara 2 pola yang cocok tidak termasuk pola yang cocok itu sendiri.

Katakanlah file.txtmengandung:

Bla bla bla
firstmatch
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
secondmatch
The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.

Saat ini, banyak sedperintah "antara 2 pola yang cocok" tidak akan dihapus firstmatchdan secondmatch.

Saya ingin hasilnya menjadi:

It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.

Jawaban:


15

Inilah salah satu cara Anda bisa melakukannya:

sed '1,/firstmatch/d;/secondmatch/,$d' 

Dijelaskan: Dari baris pertama ke baris yang cocok dengan firstmatch , hapus. Dari baris yang cocok dengan secondmatch ke baris terakhir, hapus.



5

sedSolusi lain akan gagal jika firstmatchterjadi pada baris 1 1 .

Sederhanakan, gunakan rentang tunggal dan regex 2 kosong :
cetak semuanya dalam rentang itu, tidak termasuk ujung rentang (pencetakan otomatis dinonaktifkan) 3 :

sed -n '/firstmatch/,/secondmatch/{//!p;}' infile

atau, lebih pendek, hapus semua yang tidak ada dalam rentang itu dan hapus juga kisaran yang berakhir:

sed '/firstmatch/,/secondmatch/!d;//d' infile


1: Alasannya adalah bahwa jika alamat kedua adalah regexp, maka memeriksa kecocokan akhir akan dimulai dengan garis mengikuti garis yang cocok dengan alamat pertama .
Oleh karena itu, /firstmatch/tidak pernah dievaluasi untuk baris pertama input, sedhanya akan menghapusnya karena cocok dengan nomor baris 1,/RE/dan beralih ke baris 2 di mana ia memeriksa apakah baris cocok/firstpattern/

2: Ketika REGEX kosong (yaitu //) sedberperilaku seolah-olah REGEX terakhir yang digunakan dalam perintah terakhir diterapkan (baik sebagai alamat atau sebagai bagian dari perintah pengganti) ditentukan.

3: ;}sintaksnya adalah untuk sedimplementasi modern ; dengan yang lebih lama gunakan baris baru, bukan titik koma atau misalnya ekspresi terpisahsed -n -e '/firstmatch/,/secondmatch/{//!p' -e '}' infile


Bisakah Anda menjelaskan apa yang //sedang dilakukan (di dalam {…})?
G-Man Mengatakan 'Reinstate Monica'

Terima kasih, tetapi Anda jatuh ke dalam perangkap saya. Saya tahu itu //berarti ungkapan reguler terakhir yang digunakan; dari semua yang saya baca, itu seharusnya /secondmatch/. Saya telah memverifikasi melalui pengujian bahwa perintah Anda berfungsi, dan saya menyimpulkan bahwa itu berfungsi sebagai /firstmatch|secondmatch/(yang telah Anda konfirmasi), tetapi saya tidak dapat menemukan dokumentasi apa pun (bahkan dokumen POSIX yang Anda tautkan ke atau GNU manual sed ) yang menjelaskan perilaku ini. ... (Lanjutan)
G-Man Says 'mengembalikan Monica'

(Lanjutan) ... Menghibur eksperimen: (I) Dalam sed: (1) Jika saya melakukannya /first/,4, maka //bertindaklah seperti /first/. (2) Jika saya melakukannya 2,/second/, maka //mendapat kesalahan "tidak ada ekspresi reguler sebelumnya". (Saya menemukan ini kegagalan mencolok untuk mengikuti perilaku yang ditentukan.) (3) Menambahkan --posixtidak mengubah salah satu di atas. (II) Dalam program lain: (4) Dalam vi, setelah /first/,/second/, //tindakan seperti /second/(dan bentuk lain juga merupakan implementasi rasional dari aturan yang didokumentasikan). … (Lanjutan)
G-Man Mengatakan 'Reinstate Monica'

(Lanjutan) ... (5)  awktampaknya tidak memiliki gagasan tentang "RE terakhir yang digunakan"; //mengacu pada non-karakter sebelum atau setelah karakter apa pun. (Saya mengundang Anda untuk mencoba echo -- | awk '{ gsub(//, "cha"); print }'.)
G-Man Mengatakan 'Reinstate Monica'

Jadi, Anda membaca "REGEX terakhir yang digunakan dalam perintah terakhir" sebagai "REGEX terakhir yang digunakan dalam perintah terakhir" dan Anda (dengan benar) menebak artinya /first|second/. Beruntungnya kamu. Saya menyebutkan program lain untuk menunjukkan bahwa ini bukan konvensi regex seluruh sistem. Siapa pun yang menambahkannya sedtidak perlu menambahkannya vim, di mana itu akan masuk akal. :-) ⁠
G-Man Mengatakan 'Reinstate Monica'
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.