限りなくmoonshine...

GarageBandなどDTMネタとバンドネタと甘いもの中心に。たぶん。

Solarisのawkは。

2007-05-15 20:54:13 | work

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問題」を少ない文字数でプログラミングし、「短い方が
 エライ」みたいに盛り上がってる内容は、ちょっと好きになれないな。
 別に、何行に渡って書いてもいいじゃん。この程度だったら。と思いますが如何。
 こういう後輩がいたら、すげー使いにくいだろうな。
 そんなことよりも、ちゃんとコメント入れろよ、とか(笑)。
 趣味のプログラマじゃない、ってことだな。



最新の画像もっと見る