2006年9月2日土曜日

sedを使ったテキスト書き換え処理を覚えよう (2)

先日、

sedを使ったテキスト書き換え処理を覚えよう

というのを思いつきで書いてみたら、なんだか自分でもノリノリな気分になってしまったので、今日は、その落ち穂拾いみたいな内容で行ってみることにします。



(注意) ブラウザによっては、長い行が、右端にはみ出して、見えなくなってしまっているようです。すみませんが、その点、ご注意ください。はみ出した部分を含むように、全体をコピーして、エディタなどへペーストすれば、とりあえず見えるようになります。





■ 今日の例題はITmediaのRSS



前回は、Impress WatchのWebサイトのRSSの書き換えを例としてあげました。じゃあ今日は・・・ということで、ITmediaを選びました。



ITmediaって、しばらく前にリニューアルして・・・なんか個人的に、どこを見ていいのか、バラバラなかんじで、とまどってしまうのですが、たとえば、ITmediaのRSSって、いったいどこから採れるのか、わかりにくいきがしませんか?
最近になって、ようやく理解したのですが、「ITmedia」というサイトと、「+D」というサイトの入り口が、ごちゃごちゃに交じり合っていて、なんだか、設計を失敗した二世帯住宅?みたいな・・・



あ、ずいぶんと話が脱線しました。



まずは、ITmediaのRSSを取得してみましょう。



わたしはRSSリーダーとして、もっぱら、Mozilla Firefoxと、Sageという拡張機能(extension)を使用しています。

参考までに・・・
Firefox ― Webブラウザ

まず、 http://www.itmedia.co.jp/ をFirefoxで開いて、Sageの虫眼鏡のアイコン「フィードを発見する」をクリックすると、いくつか、RSSを見つけてくれます。



200609011



たくさんあるなぁ、と思うのですが、実際にこの中身を眺めてみると、なんか情報が少ないかなぁ~と思ったりするのです。



次に、 http://plusd.itmedia.co.jp/ をFirefoxで開いて、Sageでフィードを探してみますと・・・



200609012



なーんだ、PCとかゲームとかの話題は、こっちの方に入ってたんですね。さきほど、設計ミスの2世帯住宅と言ったのは、こういうふうに2つに分かれてたんだねぇ・・・という意味の皮肉でした(笑)。



■ たくさんRSSが見つかったねぇ~



というわけで、以下の6つのRSSを選んでみました。

ITmedia Top Story 最新記事一覧
http://www.itmedia.co.jp/news/fortop/
RSSは… http://rss.itmedia.co.jp/rss/1.0/topstory.xml



ITmedia +D 最新記事一覧
http://plusd.itmedia.co.jp/
RSSは… http://rss.itmedia.co.jp/rss/1.0/plusd.xml



ITmedia News 速報 最新記事一覧
http://www.itmedia.co.jp/news/bursts/
RSSは… http://rss.itmedia.co.jp/rss/1.0/news_bursts.xml



+D LifeStyle 最新記事一覧
http://plusd.itmedia.co.jp/lifestyle/
RSSは… http://rss.itmedia.co.jp/rss/1.0/lifestyle.xml




+D PC USER 最新記事一覧

http://plusd.itmedia.co.jp/pcuser/
RSSは… http://rss.itmedia.co.jp/rss/1.0/pcuser.xml




+D Games 最新記事一覧

http://plusd.itmedia.co.jp/games/
RSSは… http://rss.itmedia.co.jp/rss/1.0/games.xml


■ 今回の課題も、sedによるRSSの書き換え



さてさて、前回のImpress Watchのサイトの例では、URLから「?ref=rss」というのを削除したいなぁ~、という課題を出して、sedで書き換える方法を紹介しました。



今回のITmediaのサイトのRSSでは、「?ref=rss」はついていませんでした。じゃあ問題ないかというとそうとも言えませんでして、たとえば、「+D PC USER 最新記事一覧」のRSSから見えている

USBメモリに“思い出”をずっと残しておけますか?

という記事のURLは



http://cgi.itmedia.co.jp/rss/pcuser_1.0/plusd/pcuser/articles/0609/01/news112.html



となっているのですが、実際にこのアドレスをWebサーバにリクエストしてみると、



Location: http://plusd.itmedia.co.jp/pcuser/articles/0609/01/news112.html



というヘッダが帰ってきて、リダイレクトされてしまいます。ちなみに、こういうWebサーバとのやり取りは、wgetコマンドを使って、「wget -d http://cgi.~」と-dオプションつきで実行すると、詳しく眺めることができます。



結局、Webブラウザで表示されるのは、



http://plusd.itmedia.co.jp/pcuser/articles/0609/01/news112.html



というアドレスのページです。



「http://cgi.~」というリンクをブラウザでクリックしたはずなのに、実際にブラウザで表示されるのは「http://www.~」のページになります。またしても、RSSで見えているURLと、実際の記事のURLが異なる、という状況が発生しています。



この場合に困ったことというのは、「ブラウザでリンクをクリックして既読となっているはずの記事が、Sageで見えているRSSの一覧のほうでは既読にならない」、ということが起きることです。みんな、こういう既読状態にならないことって、気にしていないのかなぁ?



今回の課題は、実は前回の2個目の課題よりはずっと簡単なのですが、以上のようなURLの書き換え処理を、sedでやってみましょう、ってことにします。


■ 書き換えの規則性を見つける!



sedは、一定の規則にしたがって、テキストを書き換えるツールです。だから、sedを用いてテキスト書き換え処理をしたい場合は、「いかにして、書き換えの規則性を見つけるか」が、最初の問題となります。



まずは、2つのURLを見比べてみましょう。



http://cgi.itmedia.co.jp/rss/pcuser_1.0/plusd/pcuser/articles/0609/01/news112.html



http://plusd.itmedia.co.jp/pcuser/articles/0609/01/news112.html



上がRSSに入っているリンクアドレス、下が実際にブラウザで表示されるときのリンクアドレスです。



規則性は見つかりましたか?

/pcuser/articles/0609/01/news112.html

という部分が、両者で共通してますよね。たった1つの例だけから、「これが規則だ!」と決め付けるのは無理があるので、ほかのリンクについても、この規則が成り立つか、一応、確認してみる必要があります。・・・で、どうやら大丈夫そうです。



というわけで、書き換えの規則としては、



「http://cgi.itmedia.co.jp/rss/pcuser_1.0/plusd」を、「http://plusd.itmedia.co.jp」に置換する



で、うまくいきそうです。これは単純なテキスト置換処理なので、sedではsコマンドだけでできます。sedのコマンドで表現すると、こうなります。



sed 's|http://cgi.itmedia.co.jp/rss/pcuser_1.0/plusd|http://plusd.itmedia.co.jp|'



前回も少し触れましたが、sコマンドは、2文字目にデリミタ(区切り文字)を指定します。通常、デリミタとして「/」(スラッシュ)を使うことが多くて、「s/ABC/abc/」のように書くのが一般的です。しかし、sコマンドのデリミタは、「/」でなければいけないということは無くて、「:」(コロン)を使って「s:ABC:abc:」としてもいいし、「|」(パイプ記号)を使って「s|ABC|abc|」としてもかまいません。



今回、置換処理対象がURLだったので、「/」や「:」が置換対象の文字列に使われています。もしもデリミタで「/」を使う場合は、URL中の「/」がデリミタだと思われないようにする、エスケープ処理が必要になります。「/」をエスケープさせるには「\」記号をつけて、「\/」とします。そのため、先ほどのsedコマンドで、デリミタを「/」とした場合は、



sed 's/http:\/\/cgi.itmedia.co.jp\/rss\/pcuser_1.0\/plusd/http:\/\/plusd.itmedia.co.jp/'



・・・なんだかえらく見にくくなってしまいます。そのため、デリミタとして「|」を使ったのでした。sed遣いに大切なこと・・・いやいや、sed使いをめざすならば、こういった臨機応変さとか、自分以外の人がみてもわかりやすいように、と真心をこめてsedコマンドを記述するような、心配りも必要ですね。なんてな。


■ シェルのパイプ | とかリダイレクト > とかも憶えとこう



Unix遣いに大切なことは・・・スマートに仕事をこなすこと・・・です。



今回の、sedを用いたRSS書き換え処理の場合、



  1. wgetでRSSをダウンロードして、ファイルに保存


  2. 保存したファイルをsedで読み込みながら、置換処理を行って、ファイルに保存


という2段階の処理になるかと思います。これ、ちょっとスマートじゃないです・・・途中で、ファイルに保存している部分が、スマートじゃないんですね。



Unixの場合、こういうタイプの処理は、パイプをつかって、ファイルを作らずに、並列実行するのが、粋というものなのです。



パイプとは、「|」という記号で表して、

コマンド1 | コマンド2

のようにコマンドを実行します。こうすると、コマンド1とコマンド2が並列実行されて、しかも、コマンド1の標準出力が、コマンド2の標準入力へ接続されます。



C言語のプログラミングをやったことのある方なら、標準出力とか標準入力はよく知っているかと思いますが、ものすごく乱暴に説明してしまうと、こんなかんじです。



標準入力とは、入力ファイルを指定しなかったときに使われる、データの入力元のことです。普通は、キーボードから入力した文字列が、標準入力として使われます。「sed 's/ABC/abc/'」というコマンドを実行すると、キーボードから入力した文字列が置換されていきますが、これは、sedが標準入力からデータを読み取っているのです。

標準出力
とは、データの出力先ファイルをとくに指定しなかったに使われる、データの出力先のことです。普通は、画面に文字列が出力されていきます。「sed 's/ABC/abc/'」というコマンドを実行すると、置換後の文字列が画面に表示されていきますが、これは、sedが標準出力へデータを書き出しているのです。



たとえば、

sed 's/ABC/abc/' | nkf -e

とすれば、sedとnkfが並列実行されつつ、sedの出力がそのままnkfの入力として使われます。ちなみに、nkfは、文字コードを変換するコマンドです。



パイプのほかに、リダイレクトも憶えておきましょう。リダイレクトには、入力のリダイレクトと、出力のリダイレクトがあります。



入力のリダイレクトは、< 記号を用いて、以下のようにコマンドを実行します。

sed 's/ABC/abc/' < file1.txt

< がリダイレクトの記号。file1.txtはファイル名です。この場合、sedコマンドの標準入力として、ファイルのfile1.txtが使われることになります。つまり、file1.txtの内容がsedに読み込まれて、置換処理が行われ、結果は標準出力(この場合、画面)へ出てくることになります。




(実行例)



% cat file1.txt (ファイルfile1.txtの内容を表示する)
ABCDEFG     (ファイルの内容)
abc def     (ファイルの内容・つづき)
% sed 's/ABC/abc/' < file1.txt
abcDEFG     (sedの出力)
abc def     (sedの出力・つづき)



出力のリダイレクトは、> 記号を用いて、以下のようにコマンドを実行します。

sed 's/ABC/abc/' > file2.txt

> がリダイレクトの記号。file2.txtはファイル名です。この場合、sedコマンドの標準出力として、ファイルのfile2.txtが使われることになります。つまり、sedは、標準入力(この場合、キーボードからの入力)から読み出され、置換処理が行われ、結果はfile2.txtへ出力されることになります。



(実行例)



% sed 's/ABC/abc/' > file2.txt
ABCDEFG  (キーボードから入力)
abc    (キーボードから入力)
def    (キーボードから入力)
% cat file2.txt  (ファイルfile2.txtの内容を表示する)
abcDEFG   (置換されている)
abc
def


というわけで、パイプを使って


% sed 's/ABC/abc/' | nkf -e


と並列実行するのと、リダイレクトを使って


% sed 's/ABC/abc/' > file3.txt
% nkf -e < file3.txt


とするのは、意味としては同じなのですが、リダイレクトを使うと、いったん、ファイルが保存されるので(こういうファイルのことを中間ファイルと呼びます)、その分処理に時間がかかるようになります。一方、パイプなら、ファイルは作られず、すべて、メモリ上でのデータのコピーだけで処理がすすむので、処理効率が向上するのです。



RSSをダウンロードして、sedで書き換えて、ファイルに保存するまでの処理を、パイプとリダイレクトを使って、1度に実行すると、以下のようになります。



% wget -q -O - http://rss.itmedia.co.jp/rss/1.0/pcuser.xml | sed 's|http://cgi.itmedia.co.jp/rss/pcuser_1.0/plusd|http://plusd.itmedia.co.jp|' > ! pcuser.xml



wgetで指定している、「-q」オプションは、処理の進行状況などを画面に表示しないようにする指定です。別になくてもかまいません。見栄えだけのことです。そのあとの「-O -」は、ダウンロードしたデータを、ファイルに保存するのではなく、標準出力へ出力しなさい、という指示です。「-O ファイル名」と指定するのが一般的ですが、特例として、ファイル名を「-」としたとき、標準出力へ出力されるようになっています(そうなるように、wgetがそうプログラミングされている)。



そのあと、パイプ | があるので、ダウンロードしたデータは、そのままsedへ入力されることになります。



sedで置換処理が実行され、結果は、> で出力がリダイレクトされているので、ファイルpcuser.xmlに保存されることになります。


■ 正規表現を用いた置換処理



その他のRSSの書き換え処理もやってみましょう。



先ほど示した、

+D PC USER 最新記事一覧
http://plusd.itmedia.co.jp/pcuser/
RSSは… http://rss.itmedia.co.jp/rss/1.0/pcuser.xml

のRSSの書き換え処理は、sedコマンドがこうなりました。



s|http://cgi.itmedia.co.jp/rss/pcuser_1.0/plusd|http://plusd.itmedia.co.jp|

+D LifeStyle 最新記事一覧
http://plusd.itmedia.co.jp/lifestyle/
RSSは… http://rss.itmedia.co.jp/rss/1.0/lifestyle.xml

の場合は、たとえば、



http://cgi.itmedia.co.jp/rss/lifestyle_1.0/plusd/lifestyle/articles/0609/01/news091.html





http://plusd.itmedia.co.jp/lifestyle/articles/0609/01/news091.html



のように書き換えたいので、さっきと同様に、



s|http://cgi.itmedia.co.jp/rss/lifestyle_1.0/plusd|http://plusd.itmedia.co.jp|



とすればよさそうです。

+D Games 最新記事一覧
http://plusd.itmedia.co.jp/games/
RSSは… http://rss.itmedia.co.jp/rss/1.0/games.xml

の場合も同様で、たとえば



http://cgi.itmedia.co.jp/rss/games_1.0/plusd/games/articles/0609/01/news083.html





http://plusd.itmedia.co.jp/games/articles/0609/01/news083.html



へ書き換えることになるので、



s|http://cgi.itmedia.co.jp/rss/games_1.0/plusd|http://plusd.itmedia.co.jp|



です。

ITmedia News 速報 最新記事一覧
http://www.itmedia.co.jp/news/bursts/
RSSは… http://rss.itmedia.co.jp/rss/1.0/news_bursts.xml

も同様です。



http://cgi.itmedia.co.jp/rss/news_bursts_1.0/www/news/articles/0609/01/news108.html





http://www.itmedia.co.jp/news/articles/0609/01/news108.html



のようになればよいので、



s|http://cgi.itmedia.co.jp/rss/news_burst_1.0/www/|http://www.itmedia.co.jp/|'



でよさそうです。



それでは、

ITmedia Top Story 最新記事一覧
http://www.itmedia.co.jp/news/fortop/
RSSは… http://rss.itmedia.co.jp/rss/1.0/topstory.xml

の場合はどうでしょうか・・・ちょっとこれまでとは違っていて、書き換え対象のURLが、いろいろなタイプに分かれています。



書き換え元のURLの例
http://cgi.itmedia.co.jp/rss/topstory_1.0/www/bizid/articles/0609/01/news057.html
http://cgi.itmedia.co.jp/rss/topstory_1.0/www/news/articles/0609/01/news054.html
http://cgi.itmedia.co.jp/rss/topstory_1.0/www/enterprise/articles/0609/01/news051.html
http://cgi.itmedia.co.jp/rss/topstory_1.0/plusd/pcuser/articles/0609/01/news029.html



書き換え後のURLの例
http://www.itmedia.co.jp/bizid/articles/0609/01/news057.html
http://www.itmedia.co.jp/news/articles/0609/01/news054.html
http://www.itmedia.co.jp/enterprise/articles/0609/01/news051.html
http://plusd.itmedia.co.jp/pcuser/articles/0609/01/news029.html



次も見てみましょう。

ITmedia +D 最新記事一覧
http://plusd.itmedia.co.jp/
RSSは… http://rss.itmedia.co.jp/rss/1.0/plusd.xml

これも、何タイプかあります。



書き換え元のURLの例
http://cgi.itmedia.co.jp/rss/plusd_1.0/plusd/mobile/articles/0609/01/news005.html
http://cgi.itmedia.co.jp/rss/plusd_1.0/plusd/lifestyle/articles/0609/01/news111.html

書き換え後のURLの例

http://plusd.itmedia.co.jp/mobile/articles/0609/01/news005.html
http://plusd.itmedia.co.jp/lifestyle/articles/0609/01/news111.html



こうやって見ると、書き換えのパターンが、同様だといってもRSSごとに微妙に違っていたり、1つのRSS内でも複数通りの書き換えパターンがあったりしますし、何通りもあって、sedのコマンドを書く数が増えていき、だんだん、めんどくさい気がしてきました。



もうちょっと、簡単に書き換えの規則を指定できないか? ・・・ できます。正規表現を使うと、とっても簡単に指定できるようになります。



正規表現というのは、ファイル名検索とか文字列検索機能で使えるワイルドカード「*」(アスタリスク)を、何倍も強力にしたようなものです。正規表現を使うと、文字列検索で指定できる、特別な検索パターンを指定することができます。



実は、以上のすべての書き換え規則は、以下のたった1つの規則だけで、まかなうことができます。



sed 's|http://cgi.itmedia.co.jp/rss/[^/]*/\([^/]*\)/|http://\1.itmedia.co.jp/|'

(2006/9/2 訂正) *が1個抜けていました。

(2006/9/7 追記) 以下のような感じの書き換えパターンが見つかり、上記のルールだけでは不十分でした。

(書き換え前)
http://cgi.itmedia.co.jp/rss/topstory_1.0/atit/flinux/rensai/linuxtips/932newfc5dvd.html

(書き換え後)
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/932newfc5dvd.html

仕方ないので、2つの置換コマンドで対応することにしてみました。

/usr/bin/sed '
s|http://cgi.itmedia.co.jp/rss/[^/]*/atit/|http://www.atmarkit.co.jp/|g
s|http://cgi.itmedia.co.jp/rss/[^/]*/\([^/]*\)/|http://\1.itmedia.co.jp/|g
'







(2007/1/23 追記) さらに、以下のような感じの書き換えパターンが見つかり、上記のルールだけでは不十分でした。

(書き換え前)
http://cgi.itmedia.co.jp/rss/topstory_1.0/tt/tt/news/0701/19/news01.html



(書き換え後)
http://techtarget.itmedia.co.jp/tt/news/0701/19/news01.html

仕方なく、置換コマンドを1つ追加し、合計3つの置換コマンドで対応することにしてみました。

/usr/bin/sed '
s|http://cgi.itmedia.co.jp/rss/[^/]*/tt/|http://techtarget.itmedia.co.jp/|g
s|http://cgi.itmedia.co.jp/rss/[^/]*/atit/|http://www.atmarkit.co.jp/|g
s|http://cgi.itmedia.co.jp/rss/[^/]*/\([^/]*\)/|http://\1.itmedia.co.jp/|g
'

~~~追記はここまで~~~



ここで使用している正規表現について、詳しく説明していきます。




● [ ] の使い方



[~]は、[]内に列挙した文字のどれか1文字にマッチします。たとえば[ABC]は、AかBかCのどれか1文字にマッチします。マッチするのは、1文字だけです。



列挙するときに「-」(マイナス、ハイフン)も使えて、[A-N]なら、AからNまでの文字列、ようするに、[ABCDEFGHIJKLMN]と同じ意味になります。



[ ]の中に「^」を入れると、「^」のあとに列挙されている文字以外にマッチします。たとえば[^ABC]は、AでもBでもCでもない文字にマッチします。



そのため、[^/]は、/以外の1文字とマッチします。



実行例



% sed 's/[ABC]/x/'
ABCDEFG
xBCDEFG
% sed 's/[ABC]/x/g'
ABCDEFG
xxxDEFG
% sed 's/[^ABC]/x/'
ABCDEFG
ABCxEFG
% sed 's/[^ABC]/x/g'
ABCDEFG
ABCxxxx



sコマンドのフラグgの、あるなし、にも注目してください。gがない場合、1行中の一番最初にマッチした1回しか置換が行われないのに対して、gがあると、マッチするところすべてに対して置換が行われます。



● * の使い方



「*」(アスタリスク)は、その直前の文字の、0回以上の繰り返しにマッチします(言葉で説明すると、わかりにくいですね)。たとえば「A*」だと、Aの0回以上の繰り返しにマッチするので、A、AA、AAA、AAAAAAAなどにマッチします。ここが重要なのですが、長さ0の文字列にもマッチするため、何にもない「空文字」にマッチしてしまいます(ここが、正規表現と、そのほかのワイルドカード処理、ファイル名glob処理などとの違うところです)。そのため'A*B'で検索すると、「ABC」や「AABC」が検索されるのは当然として、「BC」なども検索されます。ややこしいですが「*」の性質に慣れてください。以下に、sedでの実行例を示します。



実行例



% sed 's/A*B/xxx/'
ABC     (入力)
xxxC     (ABがxxxで置換された)
AABC     (入力)
xxxC     (AABがxxxで置換された)
AAABC    (入力)
xxxC     (AAABがxxxで置換された)
BCDE     (入力)
xxxCDE    (Bがxxxで置換された)



オマケ

(1) 検索文字列「yozuca*」は、次のすべてにマッチします。
yozuc
yozuca
yozucaa
yozucaaa
yozucaaaa
yozucA
yozucぁ
検索文字列として指定するなら「yozuca*」でなくて「yozuc」で十分ってことですね。



(2) MS-DOS、Windowsのコマンドプロンプト、Unixのシェル(sh,csh,bash,...)などで、「*」をファイル名を指定するときに使えますが(ああいう処理をglobとかglobbingといいます)、あれは「*.txt」みたいな書式もあるので、ワイルドカードというものでして、このsedの正規表現の「*」とは微妙に違います。



(3) なんか忘れてるな~という気がしていて、やっぱり1つ、基本的なのを忘れていました。正規表現の「*」(アスタリスク)を紹介したのに、「.」(ピリオド、ドット)を忘れていました。「.」は*よりも単純で、『任意の1文字』にマッチする記号です。



実行例: 「A.C」にマッチする文字列を「ABC」へ置換する



% sed 's/A.C/ABC/'
AAC  ・・・入力した文字
ABC  ・・・置換結果
ACC  ・・・入力した文字
ABC  ・・・置換結果



(2006-10-22)

● \( \) と \数字 の使い方



\( \) は検索対象文字列の中に指定するもので、検索の結果、マッチした文字列が記憶されます。置換文字列に\1のように書いておくと、記憶された文字列が、\1の部分に代入されます。\( \) は何個でも指定できるので、先頭から順番に、\1、\2、\3と指定できます。



実行例



% sed 's/AB\([CDE]*\)FG\([HIJ]*\)KL/\2=\1/'
ABCDEFGHIJKL     \1にCDE、\2にHIJがマッチしているので、
HIJ=CDE        そのように置換された。
ABC          検索条件にマッチしないので、
ABC          置換されずにそのまま出力された。
ABCCCCCFGHHHHHHHKL  \1にCCCCCが、\2にHHHHHHHがマッチしている
HHHHHHH=CCCCC




● 例を解読してみよう



以上がわかれば、この例も理解できるようになるはずです。

sed 's|http://cgi.itmedia.co.jp/rss/[^/]*/\([^/]\)/|http://\1.itmedia.co.jp/|'



[^/] は、/以外の文字なので、



[^/]* は、/以外の文字が(0文字以上)連続したもの、ということになります。



ということは・・・



/[^/]*/ は、/と/で囲まれた文字列にマッチします。



実際のRSS中のURLで、この位置(~/rss/のあと)で、この検索条件にマッチするのは、pcuser_1.0、lifestyle_1.0、games_1.0、news_bursts_1.0、topstory_1.0、plusd_1.0などの文字列です。

/\([^/]*\)/
は、/と/で囲まれた部分の文字列にマッチし、また、マッチした部分が、あとで \1 として利用できるようになります。



実際のRSS中のURLで、この位置(~/rss/の次の/の次)で、この検索条件にマッチするのは、wwwもしくはplusdです。



置換後の文字列に、\1 が使われているので、この位置にマッチした文字列(この例の場合では、wwwもしくはplusd)が入ることになります。



もう一度、代表的な、置換例をあげておきます。

書き換え前



http://cgi.itmedia.co.jp/rss/topstory_1.0/www/enterprise/articles/0609/01/news051.html
http://cgi.itmedia.co.jp/rss/topstory_1.0/plusd/pcuser/articles/0609/01/news029.html



書き換え後



http://www.itmedia.co.jp/enterprise/articles/0609/01/news051.html
http://plusd.itmedia.co.jp/pcuser/articles/0609/01/news029.html



これらの書き換えが、すべて、



s|http://cgi.itmedia.co.jp/rss/[^/]*/\([^/]*\)/|http://\1.itmedia.co.jp/|



という、単一のsedコマンドで、できます。スマートだと思いませんか?



(2006/9/7 追記) 上のほうで書いたように、厳密には、もう1個、置換コマンドが必要になりました。
(2007/1/23 追記) 同様にして、上のほうで追記しましたが、新たな書き換えパターンが発見されたため、さらにもう1個、置換コマンドが必要になりました。



またしても、だいぶ長くなってしまったので、つづきはまた後日・・・


■ sedへの招待 全3話+1









0 件のコメント:

コメントを投稿