sedは日暮れて:第6回 魂の練習問題

いざゆかんsedの水面に帆を立てて。前回の復習です。

sed ”s/探す言葉/置換する言葉/” 対象ファイル > 出力ファイル

この構文でもってsedの基本、検索置換ができるようになりました。武器を持ったらがんがん使うべし。んでも文章の中の言葉の単なる検索置換はつまんにゃいのでちょっと使い方を変えてファイルの処理をしてみましょう。それは何かと尋ねたら。べんべん。大量のファイルをいっぺんに別のところにコピーしたり、移動させたいとき。バッチファイルをつくって一気にやらせちゃえますよね。そのバッチファイルつくりにsedがつかえます。

源氏物語のディレクトリgenjiがあって、その中に以下のファイルが納められているとします。

aoi.txt
hahakigi.txt
hananoen.txt
kiritubo.txt 
momijino.txt
sakaki.txt
suetumub.txt
utusemi.txt
wakamura.txt
yuugao.txt

これら10個のファイルをごっそり別のディレクトリにコピーしたい。別のディレクトリをgenjiと同じドライブの直下のworkディレクトリとします。

ファイルaoi.txtひとつだけで考えると、

copy aoi.txt workaoi.txt

という形にすればよいことがわかります(work.でもOKですね)。残りのファイルもみんなこの形にします。そんでもってこういう形がリストになったファイルをバッチファイル(~.bat)にすればいいわけです。手順は次の通り。

ファイルのリストを一つのファイルに納めます。
genjiというディレクトリにこれらしか.txtファイルがない場合
genjiディレクトリの下でls -1 *.txt > listとすれば、これらのファイルのタイトルが1行に1つずつ入ったファイルlistが作成されます。中を見てみると。
>more list
>
>aoi.txt
>hahakigi.txt
>hananoen.txt
>kiritubo.txt 
>momijino.txt
>sakaki.txt
>suetumub.txt
>utusemi.txt
>wakamura.txt
>yuugao.txt

となっています。

listファイルの中身をsedを使って書き換えます。
すべての行をcopy aoi.txt workaoi.txtのようにしたいんでしたね。目標となるcopyではじまる文をもういっぺんよ~く見て下さい。aoi.txt(注:ここは行によってsakaki.txtやutusemi.txtにかわりますね)が2回でてますね。これは新技を使わねば表現できません。どういうことかというと。1行全体の内容を表現し、かつそれをひとつの変数として別の場所で使える形にカプセル化するような正規表現を使う必要があるわけです。う~むとここで途方に暮れないで下さいね(;_;)難しい言い回しが好きなだけなの(^^;)。
形はかんた~ん。正規表現.*の周りを¥(と¥)で囲めばいいのだっ。つまり、(.*)としまあす。これは、1行に入っている文字が何であろうとそれを全部指すうえに、次回以降それらをまとめて変数1として表現させてくれる便利なやつなのです。

いよいよsed構文だい。対象ファイルはさっきのlistでした。結果ファイルは、そうですね、cptxt.batとでも名づけましょうか。ファイル名はそれこそ飯島愛でもちみもこのやろでも何でもOK(笑)ですが、拡張子だけは必ず.batにしないとばちがあたるぞお(^0^)
sed “s/(.*)/copy 1 work\1/” list >cptxt.bat

解説しますね。これは、listのすべての行に関して、
(.*)←1行ごっそりを、copy 1 work\1に変えろおと言っています。1は、(.*)のこと、つまり置換前の1行全体のことです。問題は、work\1ですね。このの大群はなんだろ。
は、エスケープ記号でした。つまり、直後のメタキャラクタの意味をなくす役割のメタキャラクタでしたよね。でも今回のはディレクトリをあらわすだけでその後の文字の意味をなくすとかなんとかいうメタな役割とは無関係です。だから、 を二つ重ねて、とし、「これは正規表現とは無関係なんだよ~ん」といわなくてはならないのだ。めんどくさいですが。workは、ふだんのworkのこと。その 後ろの\1は、ふつうののあとに、1がきているだけです。まとめておきますとsedの構文の中で、メタキャラクタとしてでないを使いたいな~と思ったら、その使いたい数より1つ多くをつけよう!ということです。で、変換結果を覗いてみましょう。

>more cptxt.bat
>
>copy aoi.txt workaoi.txt 
>copy hahakigi.txt workhahakigi.txt
>copy hananoen.txt workhahakigi.txt
>copy kiritubo.txt workkiritubo.txt
>copy momijino.txt workmomijino.txt
>copy sakaki.txt worksakaki.txt
>copy suetumub.txt worksuetumub.txt
>copy utusemi.txt workutusemi.txt
>copy wakamura.txt workwakamura.txt
>copy yuugao.txt workyuugao.txt

これで問題がなかったら、
>cptxt
と入力してこのバッチファイルを実行させます。10ファイルががんがんworkの下にコピーされるはずです。

今回のsedの用法は、copyで10ファイルを扱う程度でしたら、あまりありがたみがないかもしれませんが、rcp(リモートコピー)でたくさんのファイルのコピーをいったりきたりさせるときなどに非常に便利です。特に、UNIXとDOS間でコピーを繰り返すときなど、ファイル名がDOSだと短くなっちゃいますので、こうして自動的にやらせるようにすると、似通ったファイル名の混同もなくて安全ですねん。
今回はsedの簡単な検索置換の用例でした。次回はsedの別コマンドを扱う予定です。ではまた来週!(になればいいが(^^;) 

第7回

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です