Як я можу обробляти багаторядкові записи за допомогою awk в bash-скрипті?


14

example.txt наведено нижче

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

Я використовую скрипт bash і скажемо, що я хочу шукати ресторан за його назвою з наведеного вище файлу. Запитайте у користувача назву ресторану, і він повинен надрукувати інформацію про цей ресторан (5 рядків).

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

Я знаю, що рядок коду вище буде надрукувати весь рядок, що відповідає шаблону "McDonalds" і "KFC", але це буде просто друкувати 1-й рядок з текстового файлу, але не решту інформації про цей ресторан. Як я можу сказати, щоб він надрукував усю інформацію (5 рядків) лише з введення користувачем назви ресторану?

Відповіді:


11

За допомогою awk ви можете змінити роздільник записів . За замовчуванням це новий рядок, тому кожен рядок файлу є записом. Якщо встановити RSзмінну порожнім рядком, awk вважатиме записи розділеними порожніми рядками:

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

Я не розумію вашого запитання. Це досить розпливчасто. Це не призначення, чи використання, яке ви не отримуєте?
glenn jackman

3

Використання 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

Пояснення

Це основна sedфункція, ви можете посилатись на КОРИСНІ ОДНОКЛАДНІ СКРИПИ ДЛЯ СЕД

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

Додайте пояснення.
BMW

Але чому запропоновану редакцію відхилено? Я не змінив відповіді. Я тільки вдосконалив форматування.
ромашка

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

Наведена вище команда отримає та надрукує 4 послідовних рядки разом із поточним рядком, оскільки вона була подана у цикл for. Цифра пошуку $2=="KFC"допоможе отримати певний рядок із кількох рядків.


0

Ще одне можливе рішення:

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

Це {if($1=="KFC")print $0}може бути скорочене до просто $1 == "KFC", оскільки дією за замовчуванням для справжньої умови є друк запису.
муру

0

Досить надрукувати з рядка, що містить потрібне ім'я, до останнього рядка, що містить слово Phone(якщо, звичайно, всі записи відповідають одній схемі і завжди матимуть Phoneяк завершальний запис)

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

Якби ми хотіли це трохи ускладнити, ми могли б надрукувати рівно 5 рядків після матчу, наприклад:

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

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

stopЗмінна не буде встановлена, так що NR<=stopнічого не буде друкувати, поки /McDonalds/{stop=NR+5;}частина фактично не встановлює змінну, і що буде відбуватися тільки тоді , коли ми знаходимо матч.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.