「テキスト処理」の版間の差分

提供: Wikinote
移動: 案内検索
(クローラ)
(HTML タグを削除する)
行120: 行120:
 
さて、次は HTML ファイルから不要な部分を削除する部分だが、まずは HTML タグを削除することを考える。
 
さて、次は HTML ファイルから不要な部分を削除する部分だが、まずは HTML タグを削除することを考える。
  
  $ sed 's/<[^>]*>/g' FILE.html
+
  $ sed 's/<[^>]*>//g' FILE.html
  
 
この sed コマンドで OK ... と思ったが、そう簡単にはいかなかった。
 
この sed コマンドで OK ... と思ったが、そう簡単にはいかなかった。

2009年11月4日 (水) 22:12時点における版

以下のページも参照のこと。


一行野郎

最長行の長さを求める

AWK のマニュアルにも載っている、基礎的な一行。

$ awk '{ if (max > length()) max = length() } END { print max }' FILE

テキストファイルを横に連結

これは paste コマンドを知っているかどうか。

$ paste FILE1 FILE2

頻出コマンド Top 10

ぜんぜん役には立たないが、パイプの真骨頂が味わえる、趣き深い一行。

$ history | awk '{ print $2 }' | sort | uniq -c | sort -nr | head -n 10

IP アドレス的なもの抽出

面倒なので、先頭の 0 も許す。

$ egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' FILE

URL 的なもの抽出

使える記号は適当に。

$ egrep -o '[a-z]+://[[:alnum:]:;/._!?~%#&=+-]+'

文字単位で逆順に出力

行単位で逆順に出力する場合は、cat の反対である

$ tac FILE

でよいが、これじゃあ生ぬるい (何が)。文字単位で逆転させようじゃないか。

$ tac -rs '[^@]' FILE

@ はファイル中に出現していない文字に置き換えること。 要するに、ファイル中のすべての文字を区切り文字として逆転させている。

大文字・小文字変換

小文字をすべて大文字に変換する。下記はどちらも同じ結果を得る。

$ tr 'a-z' 'A-Z' < FILE
$ awk '{ print toupper($0) }' FILE

ランダムに 1 行出力

0 <= rand() < 1 であることに注意。

$ awk '{l[NR]=$0} END{srand();print l[int((rand()*NR))+1]}' FILE

区切り文字を変換

たぶん tr が一番簡単。

$ tr -s ' ' ',' < FILE

行番号を付ける

以下はどちらもほぼ同等。特に nl は細かい設定ができるようだが、これは man 参照のこと。

$ cat -n FILE
$ nl -ba FILE

最初の N 行をカットする

$ tail -n +$((N+1)) FILE

要するに、1 行目だけいらない (2 行目以降を出力したい) 場合、

$ tail -n +2 FILE

あ、awk でもいいか。こっちの方がわかりやすいし。

$ awk 'NR > 1' FILE

行を長さ順にソート

これ、意外と難しい。もっと美しい方法があるはず。。

$ awk '{printf("%4d ",length()); print}' FILE | sort -n | cut -c 6-

企画モノ

高効率単語帳メーカー (構想中)

高効率単語帳とは、英語の文書や文献データベースに頻出する単語とその意味を列挙した単語帳である。 頻出するが知らない単語から学習していくことで、その文献に対する読解力を効率的に上げることが可能… のはず。

自動生成に必要なパーツを考えてみよう。

  • クローラ
  • HTML タグなどの不要部分削除
  • 英単語抽出
  • 英単語数え上げ
  • 不要英単語削除 (the, is など。手作業か?)
  • 単語の意味抽出
  • 統合・整形

といったところか。

まずは Red Hat Bugzilla の高効率単語帳を作ることにしよう。 作成ポリシーは「できるだけプログラミングしない」こと。 bash と Linux のコマンドを駆使してどこまでできるか挑戦してみる。

クローラ

Red Hat Bugzilla では、URL が以下の形式になっているのでクロールするのは簡単そうだ。

https://bugzilla.redhat.com/show_bug.cgi?id=100

これは bash と curl ですぐにできるだろう。 とりあえず作ることを優先にするので、引き数やエラーに対する考慮は行わない。

#!/bin/bash
for id in $(seq 250001 251000); do
    curl -o html/$id.html "https://bugzilla.redhat.com/show_bug.cgi?id=$id"
    sleep 5 # これを短くしてはいけない
done

HTML タグをカットしながら保存した方が効率的だが、後のことも考えて今はそのまま保存することにしよう。 とりあえず新しめの 250001 から 251000 までの 1000 ページを取得することにした。

Red Hat Bugzilla にはアクセスできないページが存在し、その場合 "Access Denied" というページが表示される。 このページは不要なので削除しよう。

#!/bin/bash
for file in html/*; do
    grep -q 'Access Denied' $file
    if [ $? -eq 0 ]; then
        rm -f $file
    fi
done

grep は文字列が見つかると返り値が 0 になるので、それを利用した。 およそ 1/4 のページがアクセス不可で削除されてしまった。

$ ls html/ | wc -l
733

HTML タグを削除する

さて、次は HTML ファイルから不要な部分を削除する部分だが、まずは HTML タグを削除することを考える。

$ sed 's/<[^>]*>//g' FILE.html

この sed コマンドで OK ... と思ったが、そう簡単にはいかなかった。 複数行にわたるタグ があるのだ。例えばこんなの:

      <link href="skins/standard/global.css"
           rel="stylesheet"
           type="text/css">

これはプログラミングが必要か…。

つづく