目次 |
---|
awk のスクリプトの基本構成 |
スクリプトファイルを読み込んで gawk を実行 |
基本 |
ARGC, ARGV の使用事例 |
FILENAME, NR, FNR, NF の使用事例 |
関数の使用事例 |
batch ファイルの中に awk スクリプトを直接書き込み gawk を実行 |
凡例を作図するバッチファイルを作るawkスクリプトの解説 |
BEGIN{ データを読み込む前に行う処理 } pattern { データを読み込みながら行う処理 } END{ データ読み込み完了後に行う処理 } |
awk のスクリプトの基本構成は上に示すとおり. patternを記載すると,その条件に合致する行の処理を行う.pattern を省略すると全行の処理を行う.
もし,データ読み込みを行わないで処理を行うなら,以下のように BEGIN で囲まれた部分のみを記述する.
BEGIN{ データを読み込む前に行う処理 } |
gawk -f awk_script.awk inp_data.txt > out_data.txt |
この事例では,ファイルの設定は以下のとおり.
awk_script.awk | awk スクリプト(awk のプログラム) |
inp_data.txt | awk で処理する入力ファイル名 |
out_data.txt | awk で処理された結果を出力するファイル名 |
gawk -f awk_ARGV_test.awk test1.txt para1 para2 para3 > out_ARGV.txt |
BEGIN{ printf "ARGC=%d\n",ARGC for(i=0;i<=ARGC-1;i++){ printf "ARGV[%d]:%s\n",i,ARGV[i] } } |
ARGV[0] にはプログラム名の gawk があてられ,-f でオプション指定されたスクリプト名をとばして test1.txt 以降が ARGV[1] から ARGV[4] にあてられる.この事例では引数の数を示す ARGC は 5 となる.
ARGC=5 ARGV[0]:gawk ARGV[1]:test1.txt ARGV[2]:para1 ARGV[3]:para2 ARGV[4]:para3 |
gawk -f awk_result_2dim.awk out_2dim0_002.csv 2 33 44 59 > result_2dim0.csv |
BEGIN{ nd =ARGV[2] nu =ARGV[3] ns1=ARGV[4] ns2=ARGV[5] for(i=2;i<=5;i++){delete ARGV[i]} FS="," sigs=0;sigr=0 n=nd*2*4 } NR==nu{u=$5} ns1==NR,NR==ns2{sigs=sigs+$6;sigr=sigr+$7} END{printf "%d,%g,%g,%g\n",nd,u,sigs/n,sigr/n} |
上の awk スクリプトは,FEMの解析結果の打ち出し ( csv ファイル) の一部を読み取るものです. ここでの注意事項として,実行用バッチファイルの中で,スクリプト名の後ろに処理に必要となるパラメータを入力しています. ARGV[0] には「gawk」,ARGV[1] には入力ファイル名が格納され,ARGV[2] から ARGV[5] には数値を入力している「つもり」なのですが,「BEGIN」の中で必要な数値を変数に格納したら,ファイル名 ( ARGV[1] ) 以外の ARGV[] の配列要素を削除しています. これは,gawk は ARG[2] 以降もファイル名として読み込もうとしてエラーになってしまうため,これを避ける処置です. ちなみに「BEGIN」の中で ARGV[1] を削除すると,入力ファイル名が不定になり,うまく動きません.
データ読み込み処理部では,以下の処理を行っています.
|
|
|
gawk -f awk_NR_test.awk test1.txt test2.txt test5.txt > out_NR.txt |
BEGIN{print "FILENAME NR FNR NF $1 $2 $3 $4 $5"} { switch(FILENAME){ case "test1.txt":printf "%s %3d %5d %5d %6.1f\n",FILENAME,NR,FNR,NF,$1;break case "test2.txt":printf "%s %3d %5d %5d %6d %6d\n",FILENAME,NR,FNR,NF,$1,$2;break case "test5.txt":printf "%s %3d %5d %5d %6d %6d %6d %6d %6d\n",FILENAME,NR,FNR,NF,$1,$2,$3,$4,$5;break } } |
上のスクリプトでは,switchを使用し場合わけしているが,下のスクリプトでも同じ処理ができる.
BEGIN{print "FILENAME NR FNR NF $1 $2 $3 $4 $5"} FILENAME=="test1.txt"{printf "%s %3d %5d %5d %6.1f\n",FILENAME,NR,FNR,NF,$1} FILENAME=="test2.txt"{printf "%s %3d %5d %5d %6d %6d\n",FILENAME,NR,FNR,NF,$1,$2} FILENAME=="test5.txt"{printf "%s %3d %5d %5d %6d %6d %6d %6d %6d\n",FILENAME,NR,FNR,NF,$1,$2,$3,$4,$5} |
NR は,読み込んでいるファイルの変更によらず,スクリプトの最初から最後までの読み込んでいる現在行を示す. FNR はファイルごとに読み込んでいる現在行を示す.NF は列数を示す.
FILENAME NR FNR NF $1 $2 $3 $4 $5 test1.txt 1 1 1 0.1 test1.txt 2 2 1 0.2 test1.txt 3 3 1 0.3 test1.txt 4 4 1 0.4 test1.txt 5 5 1 0.5 test2.txt 6 1 2 1 10 test2.txt 7 2 2 2 20 test2.txt 8 3 2 3 30 test2.txt 9 4 2 4 40 test2.txt 10 5 2 5 50 test5.txt 11 1 5 1 10 100 1000 10000 test5.txt 12 2 5 2 20 200 2000 20000 test5.txt 13 3 5 3 30 300 3000 30000 test5.txt 14 4 5 4 40 400 4000 40000 test5.txt 15 5 5 5 50 500 5000 50000 |
スクリプトawk_test.awkを読み込んでout_test.txtに出力する.入力ファイルはないケース.
gawk -f awk_test.awk > out_test.txt |
BEGIN{ pi=3.141592654 x= 3.9 ;printf "int(x) : x=%+8.3f int(x)=%+d\n",x,int(x) x=-3.9 ;printf "int(x) : x=%+8.3f int(x)=%+d\n",x,int(x) x= 4.0 ;printf "sqrt(x) : x=%+8.5f sqrt(x)=%+8.5f\n",x,sqrt(x) x= 1.0 ;printf "exp(x) : x=%+8.5f exp(x)=%+8.5f\n",x,exp(x) x=exp(1) ;printf "log(x) : x=%+8.5f log(x)=%+8.5f\n",x,log(x) x=pi ;printf "sin(x) : x=%+8.5f sin(x)=%+8.5f\n",x,sin(x) x=pi ;printf "cos(x) : x=%+8.5f cos(x)=%+8.5f\n",x,cos(x) y=1;x=1.7;printf "atan2(y,x): y=%+3.1f x=%+3.1f atan2(y,x)=%+8.5f(%4.1fdeg)\n",y,x,atan2(y, x),atan2(y, x)/pi*180 y=1;x=1.0;printf "atan2(y,x): y=%+3.1f x=%+3.1f atan2(y,x)=%+8.5f(%4.1fdeg)\n",y,x,atan2(y, x),atan2(y, x)/pi*180 printf "rand() : rand()=%g\n",rand() printf "rand() : rand()=%g\n",rand() srand(5); printf "srand(x) : srand(5) rand()=%g\n",rand() srand(5); printf "srand(x) : srand(5) rand()=%g\n",rand() print s1="wantaro";s2="taro" ;printf "index(s1,s2) : s1=\"%s\" s2=\"%s\" index(s1,s2)=%d\n",s1,s2,index(s1,s2) s1="wantaro";s2="xyza" ;printf "index(s1,s2) : s1=\"%s\" s2=\"%s\" index(s1,s2)=%d\n",s1,s2,index(s1,s2) st="wantaro" ;printf "length(st) : st=\"%s\" length(st)=%d\n",st,length(st) st="wantaro" ;printf "match(st,/*/) : st=\"%s\" match(st,/taro/)=%d\n",st,match(st,/taro/) st="wantaro" ;printf "match(st,/*/) : st=\"%s\" match(st,/xyza/)=%d\n",st,match(st,/xyza/) st="wan-ta-ro" ;printf "split(st,a,\"*\"): st=\"%s\" split(st,a,\"-\")=%d a[1]=\"%s\" a[2]=\"%s\" a[3]=\"%s\"\n",st,split(st,a,"-"),a[1],a[2],a[3] st=sprintf("pi is %.5f",pi);printf "sprintf(\"*\",x) : pi=%.5f st=sprintf(\"pi is %%.5f\",pi) st=\"%s\"\n",pi,st s1="wanwantaro";s2="Kon-" ;printf "sub(/*/,s2,s1) : s1=\"%s\" s2=\"%s\" sub(/wan/,s2,s1)=%d s1=\"%s\"\n",s1,s2,sub(/wan/,s2,s1),s1 s1="wanwantaro";s2="Kon-" ;printf "gsub(/*/,s2,s1): s1=\"%s\" s2=\"%s\" gsub(/wan/,s2,s1)=%d s1=\"%s\"\n",s1,s2,gsub(/wan/,s2,s1),s1 st="wantaro";i=4;n=2 ;printf "substr(st,i,n) : st=\"%s\" i=%d n=%d substr(st,i,n)=\"%s\"\n",st,i,n,substr(st,i,n) st="WANTARO" ;printf "tolower(st) : st=\"%s\" tolower(st)=\"%s\"\n",st,tolower(st) st="wantaro" ;printf "toupper(st) : st=\"%s\" toupper(st)=\"%s\"\n",st,toupper(st) print printf "%s\n","Note) * is something of character or strings." } |
int(x) : x= +3.900 int(x)=+3 int(x) : x= -3.900 int(x)=-3 sqrt(x) : x=+4.00000 sqrt(x)=+2.00000 exp(x) : x=+1.00000 exp(x)=+2.71828 log(x) : x=+2.71828 log(x)=+1.00000 sin(x) : x=+3.14159 sin(x)=-0.00000 cos(x) : x=+3.14159 cos(x)=-1.00000 atan2(y,x): y=+1.0 x=+1.7 atan2(y,x)=+0.53172(30.5deg) atan2(y,x): y=+1.0 x=+1.0 atan2(y,x)=+0.78540(45.0deg) rand() : rand()=0.237788 rand() : rand()=0.291066 srand(x) : srand(5) rand()=0.664045 srand(x) : srand(5) rand()=0.664045 index(s1,s2) : s1="wantaro" s2="taro" index(s1,s2)=4 index(s1,s2) : s1="wantaro" s2="xyza" index(s1,s2)=0 length(st) : st="wantaro" length(st)=7 match(st,/*/) : st="wantaro" match(st,/taro/)=4 match(st,/*/) : st="wantaro" match(st,/xyza/)=0 split(st,a,"*"): st="wan-ta-ro" split(st,a,"-")=3 a[1]="wan" a[2]="ta" a[3]="ro" sprintf("*",x) : pi=3.14159 st=sprintf("pi is %.5f",pi) st="pi is 3.14159" sub(/*/,s2,s1) : s1="wanwantaro" s2="Kon-" sub(/wan/,s2,s1)=1 s1="Kon-wantaro" gsub(/*/,s2,s1): s1="wanwantaro" s2="Kon-" gsub(/wan/,s2,s1)=2 s1="Kon-Kon-taro" substr(st,i,n) : st="wantaro" i=4 n=2 substr(st,i,n)="ta" tolower(st) : st="WANTARO" tolower(st)="wantaro" toupper(st) : st="wantaro" toupper(st)="WANTARO" Note) * is something of character or strings. |
gawk "BEGIN{pi=3.141592654;for(i=-89;i<=270;i++){print 0.3*cos(i/180*pi)-7.0,1.5*sin(i/180*pi)+52.4}}" > _temp.txt |
この事例では,中心(-7.0,52.4),短半径 0.3,長半径 1.5 の楕円の座標をファイル _temp.txt に出力している. データ区切りはブランク.
gawk "{if(NR==1){sub(/#/,\"\",$0);printf \"0.3 14.5 12 0 0 ML %%s\n\",$0}}" %inp_1% > _val.txt |
gawk "BEGIN{FS=\",\"}{if(568<=NR&&NR<=610)print $2,$5*1000}" %inp_4% | psxy -R -J -B -W5 -P -O -K >> %fig_out% |
この事例では,変数 inp_4 にセットされているファイルから gawk でデータを読み取り,処理結果を GMT の psxy に渡している. awk での処理内容は,以下のとおり.
gawk "BEGIN{FS=\",\"}{if(3<=NR)print NR-2.5,$7}" dat_inp_climate.csv | psxy -R -J -Sb1u -W1 -G0/255/255 -B -K -O >> %fig_out% |
gawk "{if(NR==35) printf \"9.5 5.5 12 0 0 MR %%gm@+3@+/s\",$2}" _temp0.txt | pstext -R -J -Gred -P -O -K >> %fig_out% |
行番号を挿入するawkスクリプト
gawk "{printf \"%%03d %%s\n\",NR,$0}" test.txt > test1.txt |
凡例を作図するバッチファイルを作るawkスクリプト
001 # **************************************** 002 # Making batch file for legend drawing 003 # **************************************** 004 # Data format 005 # xlen ylen strP dx dy 006 # ipt scl llen 007 # strTX[NR] strLW[NR] strSS[NR] strSG[NR] strSW[NR] 008 # ......... ......... ......... ......... ......... 009 # ......... ......... ......... ......... ......... 010 # xlen, ylen : width and height of graph 011 # strP : position of legend box in the graph 012 # "bl" bottom left 013 # "br" bottom right 014 # "tr" top right 015 # "tl" top left 016 # dx, dy : minimum distance from axis to legend box 017 # ipt : font size in point 018 # scl : width/height of 1 font 019 # llen : length of line 020 # strTX[] : text 021 # strLW[] : element of line (width, color, type) 022 # strSS[] : type of symbol (type and dimension) 023 # strSG[] : fill color of symbol (color) 024 # strSW[] : external line of symbol (thickness and color) 025 # 026 # sx, sy : width and height of legend box 027 # xx, yy : bottom left of the legend box 028 # 029 BEGIN{ 030 FS="$"; 031 } 032 { 033 #******************************* 034 # Treatment of input file data 035 #******************************* 036 # gsub(/^ +/, "", $i);gsub(/ +$/, "", $i); 037 # erase of blanks at top and end of the strings 038 # 039 if(NR==1){ 040 for(i=1;i<=5;i++){gsub(/^ +/, "", $i);gsub(/ +$/, "", $i);} 041 xlen=$1;ylen=$2;strP=$3;dx=$4;dy=$5; 042 } 043 if(NR==2){ 044 for(i=1;i<=3;i++){gsub(/^ +/, "", $i);gsub(/ +$/, "", $i);} 045 ipt=$1;scl=$2;llen=$3; 046 } 047 if(3<=NR){ 048 for(i=1;i<=5;i++){gsub(/^ +/, "", $i);gsub(/ +$/, "", $i);} 049 strTX[NR-2]=$1;strLW[NR-2]=$2;strSS[NR-2]=$3;strSG[NR-2]=$4;strSW[NR-2]=$5; 050 } 051 } 052 END{ 053 #******************************* 054 # Calculation and output 055 #******************************* 056 nd=NR-2; 057 lmax=0; 058 for(i=1;i<=nd;i++){ 059 ss=strTX[i] 060 gsub(/(@%%)[0-9]+(%%)/,"",ss);gsub(/(@%%%%)/,"",ss);gsub(/\\[0-9]+/,"\\",ss);gsub(/(@\+)/,"",ss);gsub(/(@\-)/,"",ss);gsub(/(@\#)/,"",ss); 061 if(lmax<length(ss))lmax=length(ss); 062 } 063 #===================================== 064 # making file for legend box 065 #===================================== 066 printf "echo %d %d >_legend0.txt\n",0,0; 067 printf "echo %d %d >>_legend0.txt\n",1+lmax+1+llen+1,0; 068 printf "echo %d %d >>_legend0.txt\n",1+lmax+1+llen+1,nd; 069 printf "echo %d %d >>_legend0.txt\n",0,nd; 070 #===================================== 071 # making file for line length 072 #===================================== 073 for(i=1;i<=nd;i++){ 074 printf "echo %d %.1f >_legend%d.txt\n",1+lmax+1,nd-i+0.5,i; 075 printf "echo %d %.1f >>_legend%d.txt\n",1+lmax+1+llen,nd-i+0.5,i; 076 } 077 #===================================== 078 # difining dimension of legend box 079 #===================================== 080 sx=(ipt*(1+lmax+1+llen+1))*0.0353*scl; 081 sy=((2+ipt+2)*nd)*0.0353; 082 if(match(strP,"bl")!=0){xx=dx;yy=dy;} 083 if(match(strP,"br")!=0){xx=xlen-sx-dx;yy=dy;} 084 if(match(strP,"tr")!=0){xx=xlen-sx-dx;yy=ylen-sy-dy;} 085 if(match(strP,"tl")!=0){xx=dx;yy=ylen-sy-dy;} 086 #===================================== 087 # output of legend box 088 #===================================== 089 printf "psbasemap -R0/%d/0/%d -JX%.1f/%.1f -G255 -P -X%.1f -Y%.1f -O -K>>%s\n",1+lmax+1+llen+1,nd,sx,sy,xx,yy,"%fig_out%"; 090 printf "psxy _legend0.txt -R -J -G255/255/255 -W3 -P -O -K>>%s\n","%fig_out%"; 091 #===================================== 092 # output of line elements 093 #===================================== 094 for(i=1;i<=nd;i++){ 095 if(match(strLW[i],"---")==0)printf "psxy _legend%d.txt -R -J -W%s -P -O -K>>%s\n",i,strLW[i],"%fig_out%"; 096 } 097 #===================================== 098 # output of symbol 099 #===================================== 100 for(i=1;i<=nd;i++){ 101 if(match(strSS[i],"---")==0){ 102 if(match(strSG[i],"---")!=0&&match(strSW[i],"---")!=0){ 103 printf "echo %.f %.1f | psxy -R -J -S%s -P -O -K>>%s\n",1+lmax+1+0.5*llen,nd-i+0.5,strSS[i],"%fig_out%"; 104 } 105 if(match(strSG[i],"---")==0&&match(strSW[i],"---")!=0){ 106 printf "echo %.f %.1f | psxy -R -J -S%s -G%s -P -O -K>>%s\n",1+lmax+1+0.5*llen,nd-i+0.5,strSS[i],strSG[i],"%fig_out%"; 107 } 108 if(match(strSG[i],"---")==0&&match(strSW[i],"---")==0){ 109 printf "echo %.f %.1f | psxy -R -J -S%s -G%s -W%s -P -O -K>>%s\n",1+lmax+1+0.5*llen,nd-i+0.5,strSS[i],strSG[i],strSW[i],"%fig_out%"; 110 } 111 } 112 } 113 #===================================== 114 # output of text 115 #===================================== 116 for(i=1;i<=nd;i++){ 117 if(i==nd){ 118 printf "echo 1 %.1f %d 0 0 ML %s | pstext -R -J -P -O >> %s\n",nd-i+0.5,ipt,strTX[i],"%fig_out%"; 119 }else{ 120 printf "echo 1 %.1f %d 0 0 ML %s | pstext -R -J -P -O -K>> %s\n",nd-i+0.5,ipt,strTX[i],"%fig_out%"; 121 } 122 } 123 } |
以下の説明は,「志村拓・鷲北賢・西村克信著,AWKを256倍使うための本,2008年10月6日,株式会社アスキー・メディアワークス発行」より抜粋したものです.
FS | 入力フィールドセパレータ.デフォルトはブランク |
NR | 入力ファイルから読み込んで今までに処理した行の総数 |
gsub(正規表現,置換文字列,対象文字列) | 対象文字列中で正規表現に一致する文字列を全て置換文字列で置換する.戻り値は置換された数.対象文字列に変更を加えることに注意 |
length(対象文字列) | 対象文字列の長さをバイト数で返す |
match(対象文字列,正規表現) | 対象文字列中で正規表現に一致する位置をバイト単位で返す.一致するものがなければ0を返す |
以下の説明は,「志村拓・鷲北賢・西村克信著,AWKを256倍使うための本,2008年10月6日,株式会社アスキー・メディアワークス発行」より抜粋したものです.判りやすいです.
. | 任意の 1 文字に一致 |
* | 前の文字の 0 個以上の繰り返しに一致 |
+ | 前の文字の 1 個以上の繰り返しに一致 |
? | 前に文字があるか、1 個あるかに一致 |
^ | 行頭に一致 |
$ | 行末に一致 |
(re) | ( )で囲まれた正規表現 re をグループ化 |
[ ] | [ ]で囲まれた文字列の中の任意の 1 文字に一致 |
[^ ] | [^ で囲まれた文字列以外の文字に一致 |
re1|re2 | 正規表現re1またはre2に一致する |