@zigen 's note

awk

最終更新:

mynote

- view
管理者のみ編集可

本当は、ディレクトリ名を読み込んで、そのディレクトリにenergy.txtが存在すればディレクトリ名を付けて上位のディレクトリにコピーするawkを作りたかった。

h145:modify saitoudaisuke$ ll | awk '{print $1 $9}' total

  • rw-r--r--@データ
  • rw-r--r--@データ drwxr-xr-xIDO-CF3_Nx512_Nv1024/ drwxr-xr-xIDO-CF3_Nx256_Nv512/ drwxr-xr-xIDO-CF3_Nx128_Nv256/ drwxr-xr-xIDO-CF2_Nx512_Nv1024/ drwxr-xr-xIDO-CF2_Nx256_Nv512/ drwxr-xr-xIDO-CF2_Nx128_Nv256/
  • rw-r--r--@.DS_Store drwxr-xr-x../ drwxr-xr-x./

http://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/awk/intro/node22.html AWKのstatementsと組込関数

アクションの記述は式を並べることで行いますが、基本的に Cと同じ式が書 けます。また、次のような組み込みの数値関数が計算に使えます。表中のexpr は数を値とする式です。

atan2(y,x) y/x の逆正接(ラジアン単位) cos(expr) 余弦(与える値はラジアン) exp(expr) 指数関数 int(expr) 整数への変換 log(expr) 自然対数 rand() 0 から 1 の間の乱数 sin(expr) 正弦(与える値はラジアン) sqrt(expr) 平方根 srand(expr) 式 expr の値を乱数生成関数の種として用いる。式 expr が与えられなかった場合は、時刻が用いられる。直前の種の値を返す。 さらに以下の文字列操作用の組込関数を持っています。

gsub(r,s,t) 文字列t中で正規表現rにマッチした部分をsに置換する。 置換した個数を返す。tを指定しなかった場合は$0が用いられる。 index(s,t) 文字列sに含まれる文字列tの位置を返す。tが含まれていない場合は0を返す。 length(s) 文字列sの長さを返す。sを指定しなかった場合には$0の長さを返す。 match(s,r) 文字列sで正規表現rにマッチする位置を返す。マッチしない場合は0を返す。 RSTARTとRLENGTHの値が設定される。 split(s,a,r) 文字列sを正規表現rを用いて分割し、配列aに格納する。 rが省略された場合はFSが用いられる。配列aの内容は、いったんクリアされる。 sprintf(fmt,list) フォーマットfmtに従ってlistを整形し、結果の文字列を返す。 sub(r,s,t) gsub()と同様。ただし、最初にマッチした文字列のみが置換される。 substr(s,i,n) 文字列sのi文字目からn文字の部分を返す。nが省略された場合、 i文字目以降の部分が返される。 tolower(str) 文字列strをコピーし、大文字をすべて小文字に変換したものを返す。 アルファベットではない文字は変化しない。 toupper(str) 文字列strをコピーし、小文字をすべて大文字に変換したものを返す。 アルファベットではない文字は変化しない。 例えばgsubは次のように使います。

   % gawk '{gsub(/新潮/, "しんちょう"); print; }' miyabe.csv 
   書名,本体価格,発行,発行社,文庫,備考
   火車,743,98/02/01,しんちょう社,しんちょう文庫 み-22-8,
   かまいたち,505,96/09/01,しんちょう社,しんちょう文庫 み-22-6,短編集
   蒲生邸事件,1650,96/10/10,毎日新聞社,
       (省略)

漢字の「新潮」が「しんちょう」に置き換わっています。これは単純な置き換 えにすぎませんが、正規表現を少し覚えるともっと複雑なことができます。

少々実用的な例を上げましょう。あるディレクトリの中のファイル名が全部大 文字のとき、それを小文字に変換したいとします。

   % ls
   AWK-INTRO.AUX  FS.0.AWK  MAKEFILE        SAMPLE1.DATA  SEC3.TEX
   AWK-INTRO.DVI  FS.AWK    MAKEFILE.FINAL  SEC0.TEX      SIN.AWK
   AWK-INTRO.LOG  GSUB.AWK  MIYABE.CSV      SEC1.TEX      SUM.AWK
   AWK-INTRO.TEX  KUKU.AWK  MIYABE.DATA     SEC2.TEX

さて、ひとつひとつ

   % mv AWK-INTRO.AUX awk-intro.aux

とやりますか? 私ならこうします。

   % ls | gawk '{print "mv -v", $0, tolower($0);}'
   mv -v AWK-INTRO.AUX awk-intro.aux
   mv -v AWK-INTRO.DVI awk-intro.dvi
   mv -v AWK-INTRO.LOG awk-intro.log
   mv -v AWK-INTRO.TEX awk-intro.tex
   mv -v FS.0.AWK fs.0.awk
       (省略)

この出力は、実行したいmvコマンドの羅列になっていますね。この出力をパイ プでshに渡してやれば、お望みの結果となります 。

   % ls | gawk '{print "mv -v", $0, tolower($0);}' | sh
   AWK-INTRO.AUX -> awk-intro.aux
   AWK-INTRO.DVI -> awk-intro.dvi
   AWK-INTRO.LOG -> awk-intro.log
   AWK-INTRO.TEX -> awk-intro.tex
   FS.0.AWK -> fs.0.awk
       (省略)
   % ls
   awk-intro.aux  fs.0.awk  makefile        sample1.data  sec3.tex
   awk-intro.dvi  fs.awk    makefile.final  sec0.tex      sin.awk
   awk-intro.log  gsub.awk  miyabe.csv      sec1.tex      sum.awk
   awk-intro.tex  kuku.awk  miyabe.data     sec2.tex
   %

このように AWKを使って実行したいコマンドの列を全部作らせておいて、そ れをshに喰わせる(shの入力にする)のです。

このアイデアにsubなどの文字列操作関数などを組合わせると、沢山のファイ ルの名前の一部だけを小文字にするとか、ファイル名の一部に通し番号を振っ たりすることが簡単にできます。

なお、mvにオプション-vを付けたのは、この実行例のように変更の様子を表示 させたかっただけなので不用なら外してください。

目安箱バナー