这里有两个SOLUT。 awk中的离子。第一个是天真和重复的,但更容易遵循和学习。后者是减少重复的尝试。
这两种解决方案在处理数据文件中的错误方面都很脆弱。如果你可以自由选择实现语言,我建议你以ruby,perl或python的形式来做到这一点。
保存到一个文件(例如showinfo.sh
)并用一个参数:“cities”或“colleges”来调用,以确定模式。你也必须将数据文件重定向到标准输入。
实施例的调用(对于溶液):
./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
嗨,如果这是[功课](http://stackoverflow.com/tags/homework/info),这将有助于它作为标记这样。你试过什么了? – neillb 2011-05-10 02:02:00
还要注意你的输入列表至少有两个错误:'end_ state'和'end cities'。 – neillb 2011-05-10 02:02:41
感谢您指出错误。这不是一个家庭作业问题。我没有用awk编码。尝试在excel中没有太大的成功。我在stackoverflow.com上看到了一个单行awk代码,可以很好地处理单个字段过滤问题。 (请参阅http://stackoverflow.com/questions/4705331/filter-text-which-appears-between-two-marks。)在我的问题中,有两对标记:一个始终是“状态”。第二个可以是“城市”或“大学”。所以,我需要打印州名,然后打印城市或大学。其他字段也可以在状态下添加。 – Cyrus 2011-05-10 02:55:12