Как я могу обрабатывать многострочные записи с awk в сценарии bash?

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 строк) только с пользовательского ввода имени ресторана?

1
задан 27 March 2014 в 08:53

4 ответа

Использование 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, вы можете обратиться к ПОЛЕЗНЫМ ОДНОМЛЕТНЫМ SCRIPTS ДЛЯ SED

2
ответ дан 24 May 2018 в 10:22
  • 1
    Добавьте объяснение. – BMW 27 March 2014 в 10:36
  • 2
    Но почему предложенное редактирование отклонено? Я не изменил ответ. Я только что улучшил форматирование. – d a i s y 14 March 2017 в 15:42
$ 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" поможет получить определенную строку из нескольких строк. [ ! d0]

1
ответ дан 24 May 2018 в 10:22

Другое возможное решение:

awk 'BEGIN{FS="\n";RS="\n\n"}{if($1=="KFC")print $0}' example.txt
0
ответ дан 24 May 2018 в 10:22
  • 1
    [F1] можно сконденсировать только до $1 == "KFC", так как действие по умолчанию для истинного условия - распечатать запись. – muru 12 April 2016 в 13:40

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

$> 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;} часть не установит переменную, и это произойдет только тогда, когда мы найдем совпадение.

0
ответ дан 24 May 2018 в 10:22

Другие вопросы по тегам:

Похожие вопросы: