Bagaimana saya bisa memproses catatan multi-baris dengan awk dalam skrip bash?

13

example.txt di bawah ini

Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911

Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

Saya menggunakan skrip bash dan katakanlah saya ingin mencari restoran dengan namanya dari file di atas. Tanyakan input pengguna untuk nama restoran dan harus mencetak informasi mengenai restoran itu (5 baris).

awk '/McDonalds/> /KFC/' example.txt

Saya tahu bahwa baris kode di atas akan mencetak seluruh baris yang cocok dengan pola "McDonalds" dan "KFC" tetapi itu hanya akan mencetak baris pertama dari file teks tetapi bukan sisa informasi tentang restoran itu. Bagaimana saya bisa mengatakannya untuk mencetak semua informasi (5 baris) hanya dari input pengguna nama restoran?

Selena Gomez
sumber

Jawaban:

11

Dengan awk, Anda dapat mengubah pemisah rekaman . Secara default itu adalah baris baru, jadi setiap baris file adalah catatan. Jika Anda mengatur RSvariabel ke string kosong, awk akan menganggap catatan dipisahkan oleh baris kosong:

awk -v name="KFC" -v RS="" '$0 ~ "Restaurant: " name' example.txt
glenn jackman
sumber
Saya tidak mengerti pertanyaan Anda. Cukup kabur. Apakah tugas atau penggunaan yang tidak Anda dapatkan?
glenn jackman
3

Menggunakan sed:

$ sed -n '/KFC/,/^$/p' file
Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

$ sed -n '/McDo/,/^$/p' file
Restaurant: McDonalds
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

Penjelasan

Ini adalah sedfungsi dasar , Anda dapat merujuk SCRIP ONE-LINE BERMANFAAT UNTUK SED

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive
BMW
sumber
Tambahkan penjelasannya.
BMW
Tetapi mengapa hasil edit yang disarankan ditolak? Saya tidak mengubah jawabannya. Saya baru saja memperbaiki pemformatan.
Daisy
2
$ awk '$2=="KFC" {print; for(i=1; i<=4; i++) { getline; print}}' example.txt

Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

Perintah di atas akan mendapatkan dan mencetak 4 baris berturut-turut bersama dengan baris saat ini karena itu dimasukkan ke dalam for loop. Pola pencarian $2=="KFC"akan membantu untuk mendapatkan baris tertentu dari beberapa baris.

Avinash Raj
sumber
0

Solusi lain yang mungkin:

awk 'BEGIN{FS="\n";RS="\n\n"}{if($1=="KFC")print $0}' example.txt
Faisal
sumber
The {if($1=="KFC")print $0}dapat terkondensasi hanya $1 == "KFC", karena tindakan default untuk kondisi yang benar adalah untuk mencetak catatan.
muru
0

Cukup untuk mencetak dari baris yang berisi nama yang Anda inginkan, ke baris terakhir yang mengandung kata Phone(dengan asumsi tentu saja semua entri mengikuti pola yang sama dan akan selalu memiliki Phonecatatan penghentian)

$> awk '/5 guys/,/Phone/' restaurants.txt                                     
Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911
$> awk '/McDonalds/,/Phone/' restaurants.txt                                  
Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

Jika kami ingin menyulitkannya sedikit, kami dapat mencetak tepat 5 baris setelah pertandingan, seperti:

awk '/McDonalds/{stop=NR+5}; NR<=stop ' restaurants.txt                    

Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

The stopvariabel tidak akan ditetapkan, sehingga NR<=stoptidak akan mencetak apa pun, sampai /McDonalds/{stop=NR+5;}bagian benar-benar menetapkan variabel, dan bahwa hanya akan terjadi ketika kita menemukan pertandingan.

Sergiy Kolodyazhnyy
sumber