Grep mulai dari teks tetap, hingga baris kosong pertama


9

Saya punya file prova.txtseperti ini:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

extra1
extra2
bla

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

extra2
bla
bla

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

dan saya harus keluar dari "Mulai ambil di sini" ke baris kosong pertama. Outputnya harus seperti ini:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

Seperti yang Anda lihat garis setelah "Mulai ambil di sini" adalah acak, jadi -B-grep flag tidak berfungsi:

cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt

Dapatkah Anda membantu saya menemukan cara yang menangkap baris pertama yang akan diambil (seperti "Mulai ambil dari sini"), hingga baris kosong. Saya tidak dapat memprediksi berapa banyak garis acak yang akan saya miliki setelah "Mulai ambil dari sini".

Solusi unix yang kompatibel sangat dihargai (grep, sed, awk lebih baik daripada perl atau serupa).

Diedit: setelah tanggapan brilian oleh @ john1024, saya ingin tahu apakah mungkin untuk:

1 ° urutkan blok (menurut Mulai untuk ambil dari sini: 1 lalu 1 lalu 2)

2 ° menghapus 4 (acak abjad) garis fix1, fix2, fix3, fix4 tetapi selalu 4

3 ° akhirnya menghapus dupes acak, seperti perintah sort -u

Hasil akhir harus seperti ini:

# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4

#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

atau

# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

Output kedua lebih baik dari yang pertama. Diperlukan beberapa sihir perintah unix lainnya.


1
Ini sangat membantu untuk mengambil jejak stack untuk utas tertentu dari output java jstack. Senang saya menemukan T&J ini!
BenjaminBallard

Jawaban:


13

Menggunakan awk

Mencoba:

$ awk '/Start to grab/,/^$/' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

/Start to grab/,/^$/mendefinisikan rentang. Dimulai dengan baris apa saja yang cocok Start to grabdan diakhiri dengan baris kosong pertama ^$,, yang mengikuti.

Menggunakan sed

Dengan logika yang sangat mirip:

$ sed -n '/Start to grab/,/^$/p' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

-nmengatakan sed untuk tidak mencetak apa pun kecuali kita secara eksplisit memintanya. /Start to grab/,/^$/pmemintanya untuk mencetak garis apa pun dalam rentang yang ditentukan oleh /Start to grab/,/^$/.


Solusi Anda sempurna, saya telah mengedit permintaan saya untuk menambahkan sesuatu. Hargai bantuan Anda. Terima kasih
heisen

1

Saya memposting solusi alternatif karena mungkin berguna untuk beberapa kasus penggunaan orang. Solusi ini tidak benar-benar memenuhi persyaratan yang disebutkan, untuk solusi terbaik lihat jawaban dari @ John1024.

Anda dapat menggunakan awk dengan Record Separator diatur ke string kosong, awk akan menafsirkan ini sebagai baris baru kosong:

$ awk '/Start/' RS= prova.txt 
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

Versi ini tidak mempertahankan baris baru kosong di output. Itu juga akan menunjukkan konteks sebelum pertandingan jika ada. Perilaku ini dapat sangat berguna ketika mengambil sesuatu dalam file dan Anda ingin melihat blok baru yang dibatasi itu adalah bagian dari, misalnya:

$ awk '/random1546/' RS= prova.txt 
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Sebagai contoh saya menemukan ini berguna ketika memahami hal-hal dalam inifile.

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.