散仙学shellとプログラミングする(十二)

12790 ワード

詳細
前の文章は散仙がsedの進級について書いたが、本編ではlinuxの中でもう一つの非常に強力なテキスト処理言語gawkを見て、gawkに関する基礎があり、散仙は前の2つの文章で、紹介もあり、よく知らない友达もいて、もう一度振り返ることができる.
gawkは豊富なプログラミング言語で、高度なプログラムを書くことでデータを処理することができます.私たちが他のプログラミング言語の経験があれば、死んだJAVA、C#、Python、shell、javascriptにかかわらず、gawkを手に入れるのはとても親切で簡単です.
次にgawkの中の変数を見てみましょう.gawkの中には全部で2つの異なる変数があります.1つ目は自己変数で、2つ目はカスタム変数です.次に、具体的ないくつかのよく使われる変数を見てみましょう.
シーケンス番号
gawk固有変数名
説明
1
FIELDWIDTS
各データフィールドの正確な幅を定義するスペースで区切られた列の数
2
FS
フィールド区切り文字の出力
3
RS
入力データの行区切り
4
OFS
フィールド区切り文字の出力
5
ORS
出力データ行区切り
変数FSおよびOFSは、gawkがデータストリームのデータフィールドをどのように処理するかを定義し、デフォルトではgawkはOFSをスペースに設定します.
[search@h1 822]$ gawk   '{print $1,$2,$3}' b.txt 
a b c
solr hadoop lucene
[search@h1 822]$ cat b.txt 
a b c
solr hadoop lucene
[search@h1 822]$ gawk   '{print $1,$2,$3}' b.txt 
a b c
solr hadoop lucene
[search@h1 822]$ gawk   '{print $1,$2}' b.txt    
a b
solr hadoop
[search@h1 822]$ 

出力フィールドの区切り:
[search@h1 822]$ cat b.txt 
a b c
solr hadoop lucene
[search@h1 822]$ gawk  'BEGIN{FS=" ";OFS="-"} {print $1,$2,$3 }' b.txt 
a-b-c
solr-hadoop-lucene
[search@h1 822]$ gawk  'BEGIN{FS=" ";OFS="--"} {print $1,$2,$3 }' b.txt 
a--b--c
solr--hadoop--lucene
[search@h1 822]$ gawk  'BEGIN{FS=" ";OFS="-->"} {print $1,$2,$3 }' b.txt 
a-->b-->c
solr-->hadoop-->lucene
[search@h1 822]$ 

FIELDWIDTHSB変数は固定桁数で区切られますが、長くなるフィールドには適していません.
[search@h1 822]$ cat c.txt 
1003455
1234522
2222222
5678890
[search@h1 822]$ gawk 'BEGIN{FIELDWIDTHS="2 3 2"}{print $1,$2,$3}' c.txt 
10 034 55
12 345 22
22 222 22
56 788 90
[search@h1 822]$ 

行区切り記号の使用方法を次に示します.
[search@h1 822]$ cat cc 
        1
   2522252




        2
   2522252




        3
   2522252
[search@h1 822]$ gawk  'BEGIN{FS="
"; RS=""} {print $1,$2}' cc 1 2522252 2 2522252 3 2522252 [search@h1 822]$

次のフローを分析すると、上記の例ではFSの区切り記号を改行記号に設定します.これはgawkが行全体をフィールドとして、行区切り記号をスペースに設定し、データ行間に空白の行を残し、gawkが空白の行を区切り記号として使用することを示しています.
上のセパレータ変数のほかに、gawkには他の変数があります.
ARGC現在のコマンドライン数
ARGIND現在のファイルはARGVの中の位置
ARGVコマンドラインパラメータを含む配列
FNR現在のデータファイルのデータ行数
NFデータファイル内のフィールド総数
[search@h1 822]$ gawk  'BEGIN{print ARGC,ARGV[1]}' cc 
2 cc
[search@h1 822]$ 

ARG変数は、gawkコマンドとccパラメータを含むコマンドラインに2つのパラメータがあることを示し、最初の配列値はgawkコマンド後の最初のコマンドラインパラメータである
[search@h1 822]$ gawk  'BEGIN{print ENVIRON["HOME"] ;   print ENVIRON["PATH"] } '
/home/search
.:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/jdk/bin:/home/search/hadoop/bin:/home/search/hadoop/sbin:/usr/local/ant/bin:/usr/local/maven/bin:/home/search/hive/bin:/home/search/hive/conf:/home/search/bin
[search@h1 822]$ 

ENVIRONコマンドはSHELLの変数から値を抽出できますが、インデックスではなく文字列を使用して識別されます.
[search@h1 822]$ gawk  'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd
root:/bin/bash
bin:/sbin/nologin
daemon:/sbin/nologin
adm:/sbin/nologin
lp:/sbin/nologin
sync:/bin/sync
shutdown:/sbin/shutdown
halt:/sbin/halt
mail:/sbin/nologin
uucp:/sbin/nologin
operator:/sbin/nologin
games:/sbin/nologin
gopher:/sbin/nologin
ftp:/sbin/nologin
nobody:/sbin/nologin
vcsa:/sbin/nologin
saslauth:/sbin/nologin
postfix:/sbin/nologin
sshd:/sbin/nologin
mysql:/bin/bash
search:/bin/bash
[search@h1 822]$ 

NF変数では、データ行の最後のフィールドを指定できます.どのくらいのフィールドがあるかを知る必要はありません.
[search@h1 822]$ cat c.txt 
1003455
1234522
2222222
5678890
[search@h1 822]$ gawk  'BEGIN{FS=","} {print $1, "FNR="FNR}' c.txt 
1003455 FNR=1
1234522 FNR=2
2222222 FNR=3
5678890 FNR=4
[search@h1 822]$ 

FNR変数は、現在処理されているデータ行の合計数を含み、NR変数は、すべての合計数を含む
[search@h1 822]$ cat c.txt 
1003455
1234522
2222222
5678890
[search@h1 822]$ gawk  'BEGIN{FS=","} {print $1, "FNR="FNR}' c.txt 
1003455 FNR=1
1234522 FNR=2
2222222 FNR=3
5678890 FNR=4
[search@h1 822]$ gawk  'BEGIN{FS=","} {print $1, "FNR="FNR, "NR="NR}' c.txt 
1003455 FNR=1 NR=1
1234522 FNR=2 NR=2
2222222 FNR=3 NR=3
5678890 FNR=4 NR=4
[search@h1 822]$ gawk  'BEGIN{FS=","} {print $1, "FNR="FNR, "NR="NR}' c.txt c.txt 
1003455 FNR=1 NR=1
1234522 FNR=2 NR=2
2222222 FNR=3 NR=3
5678890 FNR=4 NR=4
1003455 FNR=1 NR=5
1234522 FNR=2 NR=6
2222222 FNR=3 NR=7
5678890 FNR=4 NR=8
[search@h1 822]$ 

次にgawkでカスタム変数を使用する方法を示します.
[search@h1 822]$ gawk  'BEGIN{test="  ,  "; print test}'
  ,  
[search@h1 822]$ 
[search@h1 822]$ gawk  'BEGIN{test="  ,  "; print test ; test=123; print test}'
  ,  
123
[search@h1 822]$ 

すでに使用されている変数は再使用できます.
gawkで算術式を使うこともできます
[search@h1 822]$ gawk  'BEGIN{x=4; x=x * 2 + 3 ; print x}'
11
[search@h1 822]$ 

コマンド側でパラメータを出力することもできます.
[search@h1 822]$ cat c.txt 
1003455
1234522
2222222
5678890
[search@h1 822]$ gawk  -f script n=1 c.txt  
1003455
1234522
2222222
5678890
[search@h1 822]$ cat script 
BEGIN{FS=","}
{print $n}
[search@h1 822]$ 
[search@h1 822]$ gawk  -f s2  n=1 c.txt 
    : 
1003455
1234522
2222222
5678890
[search@h1 822]$ cat c.txt 
1003455
1234522
2222222
5678890
[search@h1 822]$ cat s2
BEGIN{ print "    : "; n; FS="."}
{ print $n }
[search@h1 822]$ 

BEGINの前に定義した変数であれば解析できないかもしれませんが、-vパラメータを追加する必要があります.
gawkでは配列変数も簡単に使用できます.
[search@h1 822]$ gawk  'BEGIN{ a["key"]="value" ; print a["key"]}'
value
[search@h1 822]$ 

配列を巡るには、私たちが最もよく知っているforeachの方法もあります.
[search@h1 822]$ gawk  'BEGIN{ a["1"]="aa"; a["2"]="ab" ; a["3"]="ac" ; for (t in a){ print "  : ",t,"   : ", a[t]  }  }'   
  :  1    :  aa
  :  2    :  ab
  :  3    :  ac
[search@h1 822]$ 

配列変数を削除するにはdeleteコマンドを使用します.
[search@h1 822]$ gawk  'BEGIN{ a["1"]="aa"; a["2"]="ab" ; a["3"]="ac" ;  delete a["2"] ;  for (t in a){ print "  : ",t,"   : ", a[t]  }  }'
  :  1    :  aa
  :  3    :  ac
[search@h1 822]$ 


正規表現をgawkと組み合わせる方法
[search@h1 822]$ cat a.txt 
data11
data22
data111

data4561
[search@h1 822]$ gawk 'BEGIN{FS=","} /11/{print $1} ' a.txt 
data11
data111
[search@h1 822]$ 

一致オペレータを次に示します.
[search@h1 822]$ cat a.txt 
data11  test11  bbb111
data22  kkk222  ccc222
data111 ggg     jjjj

data4561 111    3333
[search@h1 822]$ gawk  'BEGIN{FS=" "} $2 ~ /^kk/{ print $0 }' a.txt 
data22  kkk222  ccc222
[search@h1 822]$ gawk  'BEGIN{FS=" "} $1 ~ /1/{ print $0 }' a.txt     
data11  test11  bbb111
data111 ggg     jjjj
data4561 111    3333
[search@h1 822]$ gawk  'BEGIN{FS=" "} $1 ~ /^1/{ print $0 }' a.txt 
[search@h1 822]$ gawk  'BEGIN{FS=" "} $1 ~ /^11/{ print $0 }' a.txt 
[search@h1 822]$ gawk  'BEGIN{FS=" "} $1 ~ /11/{ print $0 }' a.txt  
data11  test11  bbb111
data111 ggg     jjjj
[search@h1 822]$ 

$n~は、カラム内でクエリーフィルタリングを指定できます.
!番号はソートできます.正規のフィルタ:
[search@h1 822]$ cat a.txt 
data11  test11  bbb111
data22  kkk222  ccc222
data111 ggg     jjjj

data4561 111    3333
[search@h1 822]$ gawk  'BEGIN{FS=" "} $1 !~ /11/{ print $0 }' a.txt  
data22  kkk222  ccc222

data4561 111    3333
[search@h1 822]$ 

数式:
[search@h1 822]$ cat x.txt 
1 solr
2 lucne
3 hadoop 
1 solr2`
[search@h1 822]$ gawk '$1 == 1 { print $0 }' x.txt 
1 solr
1 solr2`
[search@h1 822]$ 

テキストを比較することもできます.
[search@h1 822]$ cat x.txt 
1 solr
2 lucne
3 hadoop 
1 solr2`
[search@h1 822]$ gawk '$1 == 1 { print $0 }' x.txt 
1 solr
1 solr2`
[search@h1 822]$ gawk '$2 == "hadoop" { print $0 }' x.txt   
3 hadoop 
[search@h1 822]$ 

次はgawkの構造化プログラミングを見てみましょう.
[search@h1 822]$ cat d1 
10
100
20
45
1
-11
[search@h1 822]$ gawk  '{ if ( $1 > 10 )  print $1} ' d1   
100
20
45
[search@h1 822]$ 

if-elseの例を見てみましょう.
[search@h1 822]$ cat d1 
10
100
20
45
1
-11
[search@h1 822]$ gawk  '{ if ( $1 > 10 )  print $1} ' d1   
100
20
45
[search@h1 822]$ gawk  '{ if ( $1 > 10 ) { print $1} else {  print "     10"  } } ' d1  
     10
100
20
45
     10
     10
[search@h1 822]$ 

次にwhile文を見てみましょう.
[search@h1 822]$ gawk  'BEGIN{ a=4; while (a<10){ a++ ; print a} }'
5
6
7
8
9
10
[search@h1 822]$ 

gawkはwhileでbreakとcontinueキーワードを使用することをサポートします.
[search@h1 822]$ gawk  'BEGIN{ a=4; while (a<10){ a++ ; if(a==9){ break ;} if (a==7){ continue;}    print a} }'      
5
6
8
[search@h1 822]$ 

for文を見てみましょう.
[search@h1 822]$ gawk  'BEGIN{ for(i=1;i<=10;i++) {  print "    :"i }}'   
    :1
    :2
    :3
    :4
    :5
    :6
    :7
    :8
    :9
    :10
[search@h1 822]$ 

使いやすい
gawkは出力printfコマンドのフォーマットもサポート
gawkでは、一般的な組み込み関数もサポートされています.
cos(x)コサイン
log(x)対数
rand()が0より大きく1より小さいランダム浮動小数点値
[search@h1 822]$ gawk  'BEGIN{ x=10 * rand() ; print x}'
2.37788

他にも文字列関数があり、他のプログラミングの基礎を持っている人は、次の関数を簡単に見ることができます.
length(s)文字列長をとる
split()ある記号で分割
asort()ソート
match()マッチングサブ列
tolower()小文字
toupper()大文字に変換
など
時間関数を見てみましょう.
mktime(datespec)YYY-MM-DD HHHMMSS形式で変換する時間が間違っている
strftime(format,[timestamp])フォーマット日
Systime()は現在のタイムスタンプを返します
[search@h1 822]$ gawk  'BEGIN{ print systime()}'
1408741666
[search@h1 822]$ 

カスタム関数を次に示します.
[search@h1 822]$ gawk  ' function m(){ print "        " } BEGIN{    m(); }'
        
[search@h1 822]$ 

関数名が一意であることに注意してください.
最後にgawkで関数ライブラリをカスタマイズする方法を見てみましょう.
[search@h1 822]$ cat ak 


function  a(){

print  "       "

}


function  b(i){


 for( b=i;b<10;b++){

print "           : "b
}

}



function c(){


print  rand()

}
[search@h1 822]$ cat ax
BEGIN{  a()  }
[search@h1 822]$ cat axx 
BEGIN{  c();  } 
[search@h1 822]$ gawk  -f ak -f ax
       
[search@h1 822]$ gawk  -f ak -f axx 
0.237788
[search@h1 822]$

shell端末でライブラリ関数を直接使用することはできませんが、複数の-fコマンドで複数のファイルを実行できます.