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”匹配的整行,但那只会打印文本文件的第一行,而不会打印有关该餐厅的其余信息。我怎样才能让它仅根据用户输入的餐厅名称打印所有信息(5 行)?
答案1
使用 awk,你可以更改记录分隔符。默认情况下,它是换行符,因此文件的每一行都是一条记录。如果将变量设置RS
为空字符串,awk 将认为记录由空行分隔:
awk -v name="KFC" -v RS="" '$0 ~ "Restaurant: " name' example.txt
答案2
使用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
$ 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"
将有助于从多行中获取特定行。
答案4
从包含所需名称的行打印到包含单词的最后一行就足够了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;}
部分实际设置该变量,而这只会在我们找到匹配时才会发生。