Вот два решения в awk.Первый наивный и повторяющийся, но легче следовать и учиться.Последний - попытка уменьшить повторение.
Оба решения хрупки в отношении обработки ошибок в вашем файле данных.Если вы свободны в выборе языка реализации, я предлагаю вам сделать это как-нибудь вроде ruby, perl или python.
Сохранить в файл (например, showinfo.sh
) и вызывать с одним аргументом: «города» или"колледжи", чтобы определить режим.Также вы должны перенаправить файл данных в стандартный ввод.
Пример вызова (для любого решения):
./showinfo.sh cities < states.txt
./showinfo.sh colleges < states.txt
Наивное решение:
#!/bin/bash
set -e
set -u
#mode=cities
mode=$1
awk -v mode=$mode '
/begin_state/ {st="states"; next}
/end_state/ {next}
/begin_cities/ {st="cities"; next}
/end_cities/ {next}
/begin_colleges/ {st="coll"; next}
/end_colleges/ {next}
{
if (st=="states") {
sn=$0;
}
else
if (st=="cities") cities[sn]=cities[sn]"\n"$0
else if (st=="coll") colleges[sn]=colleges[sn]"\n"$0;
}
END {
if (mode=="cities") {
for (sn in cities) { print "=="sn"=="cities[sn] } ;
}
else if (mode=="colleges") {
for (sn in colleges) { print "=="sn"=="colleges[sn] } ;
}
else { print "set mode either cities or colleges" }
}'
Второе решение, судалено повторение:
#!/bin/bash
set -e
set -u
mode=$1
awk -v mode=$mode '
/begin_/ {st=$1; next}
/end_/ {st=""; next}
{
if (st=="begin_state") { sn=$0 }
else { data[st, sn]=data[st, sn]"\n"$0 }
}
END {
for (combo in data) {
split(combo, sep, SUBSEP);
type = sep[1];
state_name = sep[2];
if (type == "begin_"mode) {
print "==" state_name "==" data[combo];
}
}
}'
Используется входной файл (как я отмечаю, он недавно изменился в вопросе):
begin_state
New York
end_state
begin_cities
Albany
Buffalo
Syracuse
end_cities
begin_colleges
Cornell
Columbia
Stony Brook
end_colleges
begin_state
California
end_state
begin_cities
San Francisco
Sacramento
Los Angeles
end_cities
begin_colleges
Berkeley
Stanford
Caltech
end_colleges
Сессия при запуске первого решения:
$ bash showinfo.sh cities < states.txt
==New York==
Albany
Buffalo
Syracuse
==California==
San Francisco
Sacramento
Los Angeles