限制在2个正则表达式到第一次出现之间的文件的Sed打印部分

时间:2013-03-14 15:31:53

标签: sed

我正在解析文字天气数据: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对我来说完全是希腊语,我无法通过它来解决问题。

2 个答案:

答案 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