Solaris 8 の awk、使えない。
仕事で次のような文字操作を行おうと思い、いつものように「 awk でサクッと」の
つもりでスクリプトを書き始めました。
1.あるディレクトリ以下にある、4ヶ月以上前に作成/更新されたファイルを
取得する。
このディレクトリにあるファイルは、一定の命名規則に則ってファイル名が
付けられていて、ファイル名のどこかに特定の文字列が存在する。
ex) aaabbb.ccc.M200701.dddeee.Z
(a,b,c,d,e の長さはそれぞれ不定)
なんとなく判るかもしれないが、「M」の後ろに西暦4桁、月2桁が来る。
2.別ディレクトリに、M+年月をディレクトリ名とする新たなディレクトリを
作成し、そこにこれらのファイルを移動する
たったこれだけのことがしたいだけである。
1は、普通に for 文に find をかましてるだけ。つまり、
for fname in `find . -type f -mtime $TWK`
do
(ここに2の処理を書く)
done
こんなだな。mtime の引数は、実際はこの前の処理で正確に日数を求めてる。
で、ファイル名に規則があるのだから、楽勝だと思いつつ、簡単に awk コマンドを
作成して shell 上で実行してみた。こんな感じに。
つまり、取得したファイル名から年月の部分を切り出し、その名前のディレクトリが
無かったら mkdir と mv、あれば mv のみ、という感じにしたいので、とりあえずは
年月を切り出す部分をテストしてみた、ということで。
もちろん、実行前に $fname にはダミーでファイル名をセットしている。
$ echo $fname | awk '{ match($1,/M[12][0-9][0-9][0-9]/); print RSTART }'
ところが。
awk: 構文エラー (1 行目の周辺)
awk: 不正な文を検出しました。 (1 行目の周辺)
なにをー。
あれ、正規表現の書き方を間違ったかな?なんて思いながら、
$ echo $fname | awk '{ match($1,"M2007"); print RSTART }'
とやってみたが。やはり、
awk: 構文エラー (1 行目の周辺)
awk: 不正な文を検出しました。 (1 行目の周辺)
となる。おかしいなぁ、と思いながら、身近にある Red Hat Enterprise Linux に
ログインして、同様に実行してみる。
$ echo $fname | awk '{ match($1,/M[12][0-9][0-9][0-9]/); print RSTART }'
17
お。正しく返ってくるじゃん。
なんだよぅ、Solaris は使えないのかよぅ。
それじゃあ、ってんで、nawk 使ってみる。
$ echo $fname | nawk '{ match($1,/M[12][0-9][0-9][0-9]/); print RSTART }'
17
なんだ、ちゃんと返ってくるんじゃん。
てことで解決。
まあ、確かに「 New version AWK 」で「 nawk 」ですが。
普段、awk で馴染んじゃってるので、驚いたじゃないですか。まったく。
そんなわけで、
$ echo $fname | nawk '{print substr($1,match($1,/M[12][0-9][0-9][0-9][01][0-9]/),7)}'
M200701
な感じで、望む結果が返ってきたのでした。
んー、でもなんかカッコ悪いなぁ。
もうちょっとスマートにならないかな。
#ちなみに、コンマ何秒の世界を争ってないですし、可読性重視でスクリプトを作成
しているので、「 FizzBuzz問題」を少ない文字数でプログラミングし、「短い方が
エライ」みたいに盛り上がってる内容は、ちょっと好きになれないな。
別に、何行に渡って書いてもいいじゃん。この程度だったら。と思いますが如何。
こういう後輩がいたら、すげー使いにくいだろうな。
そんなことよりも、ちゃんとコメント入れろよ、とか(笑)。
趣味のプログラマじゃない、ってことだな。