Bir bash betiğinde awk ile çok satırlı kayıtları nasıl işleyebilirim?


14

example.txt aşağıda

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

Ben bash script kullanarak ve ben yukarıdaki dosyadan adıyla bir restoran aramak istediğinizi söyleyelim. Kullanıcıdan restoran adını isteyin ve o restoranla ilgili bilgileri yazdırmalıdır (5 satır).

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

Yukarıdaki kod satırı "McDonalds" ve "KFC" deseniyle eşleşen tüm satırı yazdıracağını biliyorum ama bu sadece metin satırından 1. satır yazdırmak ama o restoran hakkında bilgi geri kalanı değil. Sadece restoran adının kullanıcı girişinden tüm bilgileri (5 satır) yazdırmasını nasıl söyleyebilirim?

Yanıtlar:


11

Awk ile kayıt ayırıcıyı değiştirebilirsiniz . Varsayılan olarak yeni satırdır, bu nedenle dosyanın her satırı bir kayıttır. RSDeğişkeni boş dizeye ayarlarsanız awk, kayıtların boş satırlarla ayrılmasını dikkate alır:

awk -v name="KFC" -v RS="" '$0 ~ "Restaurant: " name' example.txt

Sorunu anlamıyorum. Oldukça belirsiz. Alacağınız ödev mi yoksa kullanım mı?
glenn jackman

3

Kullanma 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

açıklama

Bu temel sedişlevdir, SED İÇİN YARARLI TEK HATTI SCRIPTS

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive

Açıklamayı ekleyin.
BMW

Peki önerilen düzenleme neden reddedildi? Cevabı değiştirmedim. Biçimlendirmeyi yeni geliştirdim.
papatya

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

Yukarıdaki komut, bir for döngüsüne beslendiği için geçerli satırla birlikte arka arkaya 4 satır alır ve yazdırır $2=="KFC".


0

Başka bir olası çözüm:

awk 'BEGIN{FS="\n";RS="\n\n"}{if($1=="KFC")print $0}' example.txt

{if($1=="KFC")print $0}Sadece kondense olabilir $1 == "KFC", gerçek bir durum için varsayılan eylem rekoru bastırmak olduğu için.
muru

0

İstediğiniz adı içeren satırdan, kelimeyi içeren son satıra yazdırmak yeterlidir Phone(elbette tüm girişlerin aynı kalıbı izlediğini ve her zaman Phonesonlandırma kaydı olacağını varsayarak )

$> 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

Biraz karmaşıklaştırmak istersek, maçtan sonra tam olarak 5 satır yazdırabiliriz, şöyle:

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

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

stopDeğişken yüzden ayarlanmaz NR<=stopkadar Bas herhangi bir şeyi /McDonalds/{stop=NR+5;}parçası aslında değişkeni ayarlar ve biz maçı bulduğunda sadece gerçekleşecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.