1

我正在解析文本天气数据:http ://www.nws.noaa.gov/view/prodsByState.php?state=OH&prodtype=hourly 并且只想获取我所在县/地区的数据。诀窍是每个文本报告都有当天早些时候的先前报告,我只对文件开头出现的最新报告感兴趣。我尝试使用 sed one 衬垫中的“两个正则表达式(包括)之间的文件打印部分”。我不知道如何让它在发生一次后停止。

sed -n '/OHZ061/,/OHZ062/p' /tmp/weather.html

我发现了这个:Sed 在模式之间打印第一个匹配结果,它适用于以下内容

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 完全是希腊语我和我无法通过它来解决我的问题。

4

2 回答 2

1

不是sed因为我不喜欢用那个工具解析 HTML,而是在这里你有一个perl在 HTML 解析器的帮助下使用的解决方案,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
于 2013-03-14T22:01:30.943 回答
1

sed 是在单行上进行简单替换的出色工具。对于其他任何事情,只需使用 awk:

awk '/OHZ061/{found=1} found{print; if(/OHZ062/) exit}' /tmp/weather.html
于 2013-03-15T03:46:22.023 回答