1

テキストの天気データを解析しています:http ://www.nws.noaa.gov/view/prodsByState.php?state = OH&prodtype = hourlyで、自分の郡/地域のデータのみを取得したいと考えています。秘訣は、各テキストレポートにはその日の早い段階からの以前のレポートがあり、ファイルの先頭に向かって表示される最新のレポートにのみ関心があるということです。sedワンライナーの「2つの正規表現の間のファイルの印刷セクション(両端を含む)」を使用しようとしました。一度発生した後に停止させる方法がわかりませんでした。

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

私はこれを見つけました:パターン間のsed printは、次のように機能する最初の一致結果です

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を解析するのが好きではないからではありませんが、ここでは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
于 2013-03-14T22:01:30.943 に答える
1

sed は、1 行で単純な置換を行うための優れたツールです。それ以外の場合は、awk を使用します。

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