我正在解析文字天气数据:http://www.nws.noaa.gov/view/prodsByState.php?state=OH&prodtype=hourly 并且只想获取我的县/地区的数据。 诀窍是每个文本报告都有当天早些时候的报告,我只对文件开头出现的最新报告感兴趣。 我试图使用“两个正则表达式之间的文件打印部分(包括)” 来自sed one liners。我无法弄清楚如何在一次发生后停止它。
sed -n '/OHZ061/,/OHZ062/p' /tmp/weather.html
我发现:Sed print between patterns the first match result适用于以下
sed -n '/OHZ061/,$p;/OHZ062/q' /tmp/weather.html
但我觉得它不是最强大的解决方案。我没有任何东西来支持稳健性的陈述,但我有一种直觉,认为可能有更强大的解决方案。
那么还有更好的解决方案吗?还有可能让我的第一个尝试的解决方案工作?如果您发布解决方案,请解释所有开关/反向引用/魔术,因为我仍在尝试发现sed和命令行工具的所有功能。
帮助你开始:
wget -q "http://www.nws.noaa.gov/view/prodsByState.php?state=OH&prodtype=hourly" -O /tmp/weather.html
ps:我看过这篇文章:http://www.unix.com/shell-programming-scripting/167069-solved-sed-awk-print-between-patterns-first-occurrence.html但是sed对我来说完全是希腊语,我无法通过它来解决问题。
答案 0 :(得分:1)
不是sed
,因为我不想用该工具解析HTML,但是在这里,您可以借助HTML解析器perl
使用HTML::TreeBuilder
。代码是逐步评论的,我认为很容易理解。
script.pl
的内容:
#!/usr/bin/env perl
use warnings;
use strict;
use HTML::TreeBuilder;
##
## Get content of the web page.
##
open my $fh, '-|', 'wget -q -O- "http://www.nws.noaa.gov/view/prodsByState.php?state=OH&prodtype=hourly"' or die;
##
## Parse content into a tree structure.
##
my $tree = HTML::TreeBuilder->new;
$tree->parse_file( $fh ) || die;
##
## Content is inside <pre>...</pre>, so search it in scalar context to get only
## the first one (the newest).
##
my $weather_data = $tree->find_by_tag_name( 'pre' )->as_text or die;
##
## Split data in "$$' and discard all tables of weather info but the first one.
##
my $last_weather_data = (split /(?m)^\$\$/, $weather_data, 2)[0];
##
## Remove all data until the pattern "OHZ + digits" found in the text
##
$last_weather_data =~ s/\A.*(OHZ\d{3}.*)\z/$1/s;
##
## Print result.
##
printf qq|%s\n|, $last_weather_data;
像以下一样运行:
perl script.pl
2013年3月14日23:00,收益率为:
OHZ001>008-015>018-024>027-034-035-043-044-142300-
NORTHWEST OHIO
CITY SKY/WX TMP DP RH WIND PRES REMARKS
DEFIANCE MOSUNNY 41 18 39 W7G17 30.17F
FINDLAY SUNNY 39 21 48 W13 30.17F
TOLEDO EXPRESS SUNNY 41 19 41 W14 30.16F
TOLEDO METCALF MOSUNNY 42 21 43 W9 30.17S
LIMA MOSUNNY 38 22 52 W12 30.18S
答案 1 :(得分:1)
sed是单行简单替换的绝佳工具。除此之外,只需使用awk:
awk '/OHZ061/{found=1} found{print; if(/OHZ062/) exit}' /tmp/weather.html