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

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

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

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

Я знаю, что строка кода выше распечатает целую строку, которая соответствует шаблону "Макдоналдс" и "KFC", но это просто распечатает 1-ю строку от текстового файла, но не остальной части информации о том ресторане. Как я могу сказать этому печатать всю информацию (5lines) от просто ввода данных пользователем названия ресторана?

13
задан 27 March 2014 в 06:53

5 ответов

С awk можно изменить разделитель записей. По умолчанию это - новая строка, таким образом, каждая строка файла является записью. Если Вы устанавливаете RS переменная к пустой строке, awk будет полагать, что записи разделяются пустыми строками:

awk -v name="KFC" -v RS="" '$0 ~ "Restaurant: " name' example.txt
11
ответ дан 23 November 2019 в 03:20

Используя 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 функция, можно относиться ПОЛЕЗНЫЕ КОРОТКИЕ СЦЕНАРИИ ЗА SED

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive
3
ответ дан 16 November 2019 в 14:06
$ 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 строки наряду с текущей строкой, потому что это питалось в для цикла. Шаблон поиска $2=="KFC" будет помогать получить конкретную строку от нескольких строк.

1
ответ дан 16 November 2019 в 14:06

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

awk 'BEGIN{FS="\n";RS="\n\n"}{if($1=="KFC")print $0}' example.txt
0
ответ дан 23 November 2019 в 03:20

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

0
ответ дан 23 November 2019 в 03:20

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

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