6 節で考察した行の分割も、 2 箇所に現われるので関数化してありますし、 7 節で考察した行の整形出力も、 後でカスタマイズできるように関数化してあります。
BEGIN{
if(TARGET=="") TARGET="yahoonews" # ターゲットフレーム名
if(DIV=="") DIV=5 # 区切りを入れる個数
N=0 # 一覧の項目数、h[]: 一覧を保存する配列
}
##### タイトルや日付の取得 #####
(ARGIND == 1 && $0 ~ /<b><font size=\+1>/){
sub(/.*<b><font size=\+1>/,"")
sub(/<\/font><\/b>.*/,"")
TITLE=$0
getline
sub(/.*<small> - /,"")
sub(/<\/small>.*/,"")
DATE=$0
}
##### 各行の取得 #####
($0 ~ /<ul>/){
sub(/<ul>/,"")
if($0 !~ /<li>/) getline
do{
# (1) 1 行を複数の <li> 行に分割して配列に保存
N=divideline($0,h,N)
getline
}while($0 !~ /<\/ul>/)
if($0 ~ /<li>/){
sub(/<\/ul>/,"")
# (1) 1 行を複数の <li> 行に分割して配列に保存
N=divideline($0,h,N)
}
}
##### END ブロック #####
END{
putheader(DATE,TITLE,N)
print "<ul>"
for(j=1;j<=N;j++){
put1list(h[j],TARGET)
if(j%DIV==0) printf "<br>(ここまで %d 件)<br><br>\n",j
}
print "</ul>"
putfooter()
}
##### ユーザ定義関数 #####
# 一つの <li> を整形して出力
function put1list(str,target)
{
if(match(str,/<a href=\"[^\"]+\">/)==0) print str
else{
printf "%s",substr(str,1,RSTART+RLENGTH-2)
printf " target=\"%s\"",target
printf "%s\n",substr(str,RSTART+RLENGTH-1)
}
}
# <br> で文字列を分割して配列 h に追加 (現在 h[1]~h[N] まで保存)
function divideline(str,h,N, tmp,j,M)
{
sub(/<br>(<br>|<\/ul>)? *$/,"",str)
M=split(str,tmp,/<br>/)
for(j=1;j<=M;j++) if(tmp[j] ~ /<li>/) h[++N]=tmp[j]
return N
}
# ヘッダの出力
function putheader(date,title,N)
{
printf "<html>\n"
printf "<head>\n"
printf "<meta http-equiv=\"Content-Type\""
printf " content=\"text/html; charset=EUC-JP\">\n"
printf "<title>Yahoo News (%s)</title>",title
printf "</head>\n"
printf "<body>\n"
printf "<h2>Yahoo News (%s: %s : %d 件)</h2>\n",title,date,N
#printf "<a href=\"%s\" target=\"%s\">(home)</a>\n",url,target
printf "<hr>\n"
}
# フッタの出力
function putfooter()
{
print "<hr>"
print "</body>"
print "</html>"
}
ターゲットフレーム名 (= TARGET) や区切りを入れる個数 (= DIV) は 変更が容易にできるようにしてあります。 例えば、Yahoo! ニュースの一覧の HTML ファイルが file1.html,file2.html,...で、 上のスクリプトファイルを yahoo2.awk とすれば、
awk -f yahoo2.awk file?.html > list.htmlのようにすれば結合された一覧の HTML ファイル list.html ができますが、
awk -f yahoo2.awk -v TARGET="another" file?.html > list.htmlのようにすれば TARGET や DIV の値を AWK のコマンドラインオプションで 変更できます。
なお、関数 putheader() の中で、charset=EUC-JP としてありますが、
これは私の環境が Unix だからではなく、
普通に Yahoo! ニュース記事をダウンロードすると EUC-JP という
漢字コードになるからです。
MS-Windows 上でも EUC-JP のまま保存した場合は上のままでいいようですが、
Shift_JIS で保存する場合は適当にその辺を修正するといいでしょう。
また、ブラウザで HTML ファイルを保存する場合、 ブラウザによっては (例えば MS-IE) 単純に保存するのではなく 色々加工して保存することもあるようで、 そのような場合は今回のスクリプトではうまく処理できないかもしれません。