Linuxの強大なawk

14443 ワード

から来ました.http://blog.dreamwe.cnを選択します
awk概要
awkはLinuxの中の一つの命令で、テキスト処理と分析をするために使われています.機能は簡単で強いです.同時に、プログラミング言語です.awkでテキストファイルを処理する場合、行為単位でログファイルを効率的に処理することができます.
awkのman文書概要:
NAME

   gawk - pattern scanning and processing language  //awk   gawk,       
    ,

SYNOPSIS

    gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
    gawk [ POSIX or GNU style options ] [ -- ] program-text file ...

    pgawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
    pgawk [ POSIX or GNU style options ] [ -- ] program-text file ...


    Gawk is the GNU Project?. implementation of the AWK programming language.  It
    conforms to the definition of the lan-
    guage in the POSIX 1003.1 Standard.  This version in turn is based on the 
description in The  AWK  Programming  Lan-
    guage,  by  Aho,  Kernighan, and Weinberger, with the additional features
 found in the System V Release 4 version of
    UNIX awk.  Gawk also provides more recent Bell Laboratories awk extensions, 
and a number of GNU-specific extensions.




【 】         ,Gawk GNU(      )  ,  unix awk,          
 awk   。   Linux  awk(gawk)     。     ,          。
使い方
コマンドの一般的な使い方は以下の通りです.
   :awk [options] 'script' [var=value] file(s) 
   :awk [options] -f scriptfile [var=value] file(s)

【  】    options     。   :'script' awk     ,    。var=value 
  ,file(s)           ,             。    -f scriptfile
              ,      。
オプション→F fs
区切り記号を指定します.awkのデフォルトの区切り記号はスペース記号です.
オプションのmanドキュメントの要約
-F fs
   --field-separator fs //     
          Use fs for the input field separator (the value of the FS prede-
          fined variable).  
eg
[  1] //        " "
# echo "hello hh"| awk '{print $1;print $2}'
hello
hh

【  】    ,     -F  ,        " "  hello hh     ,     
   :“hello”,      :“hh”。$1 $2     ,               。

[  2]
# echo "hello:hh"| awk -F :  '{print $1;print $2}'
hello
hh

【  】  -F      ":"    hello:hh ,    [  1]
位置変数0,1,$2.
nは位置パラメータであり、n番目のフィールドまたは分離後のn番目の位置の文字列0は、行全体のNFを表します.最後から1番目の位置の文字列を表します.NF-1は、下から2番目の位置を表します.これに類推します.
eg[判例1]艦cat pass.log/処理する対象ファイルのpass.logを一部切り取りました./etc/passwd root:x:0:0:root:/root:/bin/bash bin:1:1:bin:/logn:/sbin:/nologn/nologn
# awk -F : '{print ;}' pass.log 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

【  】 "print;"         , $0 


[  2]
# awk -F : '{print $0;}' pass.log 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

【  】 "print $0;"     
eg
# awk -F : '{print $1 "   "  $NF;}' pass.log 
root   /bin/bash
bin   /sbin/nologin
daemon   /sbin/nologin

【  】    ":"              ,           ,          
オプション-f program-file
スクリプトをテキストファイルに書き込み、awkコマンドの処理プログラムをオプション-fであるスクリプトファイルに指定します.処理プログラムが複雑な場合は、このような方式が一般的です.
マン文書の要約
-f program-file 
    --file program-file //--file  -f    
         Read the AWK program source from the file program-file,  instead
         of  from  the  first  command  line  argument.   Multiple -f (or
         --file) options may be used.
eg
[   ]

# vi sc.awk //    
{print $1 "   "  $NF} //        sc.awk 
//vi   ,  sc.awk    。


# awk -F : -f sc.awk  pass.log  //pass.log    pass.log  。
root   /bin/bash
bin   /sbin/nologin
daemon   /sbin/nologin

【  】        【#awk -F : '{print $1 "   "  $NF;}' pass.log】   
'{print $1 "   " $NF;}'    sc.awk ,  ,             ''  。

【  】   vi   ,   echo "{print $1 "   "  $NF}" >sc.awk         
awkプログラム構造
awk処理プログラムはBEGIN、本体、ENDからBEGIN文ブロックBEGIN{}を構成します.
eg
# vi sc.awk //    
# awk program's Begin block  //【  】          ,    
BEGIN{print "here is the awk begin!!"} //BEGIN   
{print $1 "   "  $NF}    


# awk -F : -f sc.awk  pass.log 
here is the awk begin!! //BEGIN          
root   /bin/bash
bin   /sbin/nologin
daemon   /sbin/nologin

【  】         ,BEGIN                。      。
メイン部分は、テーマ部分が{}で表されていますが、BEGINの後、ENDの前に書いてあります.前文で使われている’print’は全部プログラム主体です.
eg
# vi sc.awk //    
# awk program's main block //【  】          ,    
BEGIN{print "here is the awk begin!!"}
{
        print "this is main"
        print $1
}

# awk -F : -f sc.awk  pass.log 
here is the awk begin!!
this is main    //           print "this is main"
root            //        print $1
this is main
bin
this is main
daemon


【  】       ,            。
END文ブロックとBEGIN文ブロックが似ているEND{}コマンドは最後に実行されます.一回だけ実行されます.
eg
# vi sc.awk //    
# awk program's end block //【  】          ,    
BEGIN{print "here is the awk begin!!"}
{
    print $1
}

END{    
    print "ok,awk operate to the end"   //end      
}

# awk -F : -f sc.awk  pass.log 
here is the awk begin!!
root
bin
daemon
ok,awk operate to the end   //end       
変数
awkの処理プログラムでは変数の申明と変数の使用ができます.説明方式はvarName=varValueです.
eg 124は変数を通してファイルの行数を計算します.
# vi sc.awk //    
# awk program's var block //【  】          ,    
BEGIN{
        nu=0;           //          
}

{
    nu ++;              //       ,      1
    print nu " " $0    //           
}

END { 
    print "totall lines is " nu;    //         ,       
}

# awk -F : -f sc.awk  pass.log 
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
totall lines is 3

【  】 nu=0     ,     ,    nu  。   bash  $  
コマンド変数
コマンド変数というのは、awkコマンドではなく変数がコマンドから入ってきたからです.コマンド外部から変数を導入すると、コマンドオプション[var=value]でshellの変数をawk処理プログラムに導入することができます.
   : awk [options]  -v varname=varvalue 'script' file(s) 
   : awk [options] 'script' varname=varvalue  file(s) 

【  】      -v    ,     man      [--]
eg 124方式一
# awk -F : -v  aa="haima"  '{print aa " " $1}' pass.log 
haima root
haima bin
haima daemon

【  】 {print aa " " $1}            aa,aa   haima。      $1
eg 124方式二
# awk -F :  '{print aa " " $1}' aa="haima"  pass.log 
haima root
haima bin
haima daemon
インライン変数
内蔵変数はawkプログラムにシステムが持つ変数で、それぞれに意味があります.
FS      ,    【FS=":";】          【-F :】
IGNORECASE        ,IGNORECASE=true           
NF      ,                
NR      ,              
OFS        (        )
ORS         (         )

IGNORECASE            centos6.5
eg 124 FS
# vi sc.awk 
# awk program's FS  //【  】          ,    
BEGIN{
        FS=":" // HAIMA    ,
}

{
        print $1
}

# awk -f sc.awk  pass2.log 
root
bin
daemon

【  】 FS=":"    BEGIN   ,         -F :  
eg𞓜NFNR
# vi sc.awk 

# awk program's NF NR //【  】          ,    
{
        print  NR   " totall fileds" NF //     ,       
}

END{
        print "line numbers:" NR //END       

 }

# awk -F:  -f sc.awk pass.log 
1 totall files:7
2 totall files:7
3 totall files:7
line numbers:3

【  】  END         NF
eg|OFS ORS
# awk -F : 'BEGIN{OFS="|";ORS=" LinEnd
"}{print $1, $2;}' pass.log root|x LinEnd bin|x LinEnd daemon|x LinEnd 【 】 BEGIN OFS="|", “|” , ORS=" LinEnd
" "linEnd
" "
" , “
” , 【 】 “{print $1, $2;}” , "," 。 {print $1 $2} 。 awk 。
awkの作業原理
前のケースを通して、awkの機能は大体分かりました.awkの仕事の流れをまとめます.
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'  

   :  BEGIN{ commands }       ;

   :        (stdin)    ,    pattern{ commands }   ,     
  ,               ,           。

   :         ,  END{ commands }   。 

BEGIN    awk               ,          ,       、 
                 BEGIN    。

END    awk                  ,                  
   END      ,          。 

pattern                ,      。      pattern   ,   
  { print },           ,awk              。

【  】awk      。               。     ,     awk    
   ,         。
フロー制御
if...else if...else awkは、javaのif文のような論理制御を行うことができます.
構文は以下の通りです.
if(   )
    {  1} 
else if(   ) 
    {  2}
else
    {  3} 
eg
# vi nsc.awk  //    awk  
# test for  "if.. else if.. else " //    ,   
{
 if(NR%2==0)
    { print $2 " evenline"}    //              evenline
else if (NR%3==0) 
    {print $3 " thrirdline"} // 3    ,           thrirdline
else
     {print $NF " othersLine"} //               othersLine

# awk -F :  -f nsc.awk  /etc/passwd 
/bin/bash othersLine
x evenline
2 thrirdline
x evenline
/sbin/nologin othersLine
ループステートメント
awkもforを支持して、while、do.whileの3種類の循環文、文法はjavaの中で基本的に同じです.
forサイクル
フォーマット:for(変数;条件;表現){文}
# awk 'BEGIN{ total=0; i=0; do {total+=i;i++;} while(i<=100) print total; }'
5050
whileサイクル
フォーマット:while(表現){文}
# awk 'BEGIN{ test=100; total=0; while(i<=test){ total+=i; i++; } print total; }'
5050
ド.while
フォーマット:do{文}while(条件)
# awk 'BEGIN{ total=0; i=0; do {total+=i;i++;} while(i<=100) print total; }'
5050

# awk 'BEGIN{ total=0; i=1000; do {total+=i;i++;} while(i<=100) print total; }'
1000    //  i      i<=100   do        ,    total  1000

【  】do.. while           ,   do     ,   ,    。
break、continue
awkもbreakとcontinueのコントロールをサポートしています.breakとcontine ueは循環体で使わなければなりません.breakは直接的にサイクルから飛び出すので、もう循環contine ueを実行しないと次のサイクルにジャンプします.
nextコントロール
nextは単語の意味から私のcontinueと似ています.確かにそうです.nextはcontiueと似たような機能を持っています.nextは本行のデータ処理から飛び出すだけで、次の行のデータを処理します.contiueは今回の循環から飛び出すので、次回の循環を実行します.
eg 124は行番号6-9行のデータをスキップします.
# awk -F :  '{if(NR>5&&NR<10)next; print NR, $1}' /etc/passwd
1 root
2 bin
3 daemon
4 adm
5 lp
10 uucp
11 operator
12 games
13 gopher
14 ftp
15 nobody

【  】 if(NR>5&&NR<10)next;      6-10,           。
【  】   next       ,          ,  next     awk    ,  
   BEGIN  ,       END   ,   。
exit制御
現在実行されていない主体の内容を終了し、ENDブロックに内容があれば、ENDブロックの内容を実行します.この場合、3つの状況が発生します.
状況一:exitはBEGINブロックで使用し、exit現在位置から退出し、直接ENDブロックを実行する場合二:exitは本体で使用し、exit現在位置から退出し、直接ENDブロックを実行する場合二:exitはENDブロックで使用し、exit現在位置から退出し、ENDが速いので、実行しない.
eg|exitは本体で使用します.
# awk -F :  '{if(NR>5){exit};print NR, $1}END{print "end"}' /etc/passwd
1 root
2 bin
3 daemon
4 adm
5 lp
end

【  】   NR>5 ,    ,   print "end"
eg|exitはBEGINまたはENDで使用されます.
# awk -F : '{print"begin";exit;print"hh"}{print NR, $1}END{print "end"}' /etc/passwd
begin
end

【  】print "begin"     ,     END     print "end"
awkの正規表現
awkは、正規表現を用いてデータをフィルタリングし、より強力な処理能力を達成することができます.
レコードフィルタ用
レコードフィルタ、フィルタ単位として1つのレコードを使用します.
awk[options]“script”[var=value]file(s)この主体フォーマットが不変の場合、scriptの前にスクリーニングを入れます.このとき、’script’プログラム形式は、’(/express/){awk処理プログラム]’となります.ここで/express/は正規表現です.
マニュアルでファイルを作成します.
# cat target.log //  target.log
27.19.74.143 - - GET /static/image/common/faq.gif HTTP/1.1" 200 1127
110.52.250.126 -  GET /data/cache/style_1_widthauto.css?y7a HTTP/1.1" 200 1292
27.19.74.143 - - GET /static/image/common/hot_1.gif HTTP/1.1" 200 680
27.19.74.143 - - GET /static/image/common/hot_2.gif HTTP/1.1" 200 682
27.19.74.143 - - GET /static/image/filetype/common.gif HTTP/1.1" 200 90
110.52.250.126 -  GET /source/plugin/wsh_wx/img/wsh_zk.css HTTP/1.1" 200 1482
110.52.250.126 -  GET /data/cache/style_1_forum_index.css?y7a HTTP/1.1" 200 2331
110.52.250.126 -  GET /source/plugin/wsh_wx/img/wx_jqr.gif HTTP/1.1" 200 1770
27.19.74.143 - - GET /static/image/common/recommend_1.gif HTTP/1.1" 200 1030
110.52.250.126 -  GET /static/image/common/logo.png HTTP/1.1" 200 4542
110.44 -  GET /static/image/common/logo.png HTTP/1.1" 200 4542

【  】                。ip      
eg 124は含む.gifの行を選別する.
# awk '(/gif/){print $0}' target.log 
27.19.74.143 - - GET /static/image/common/faq.gif HTTP/1.1" 200 1127
27.19.74.143 - - GET /static/image/common/hot_1.gif HTTP/1.1" 200 680
27.19.74.143 - - GET /static/image/common/hot_2.gif HTTP/1.1" 200 682
27.19.74.143 - - GET /static/image/filetype/common.gif HTTP/1.1" 200 90
110.52.250.126 -  GET /source/plugin/wsh_wx/img/wx_jqr.gif HTTP/1.1" 200 1770
27.19.74.143 - - GET /static/image/common/recommend_1.gif HTTP/1.1" 200 1030
eg 124はデータが正常でない行を選別します.(targt.logの最後の行のデータはエラーデータです.)
#awk --posix '!/([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}/{print $0}' target.log
110.44 -  GET /static/image/common/logo.png HTTP/1.1" 200 4542  

【  】    ,        IP  ,ip   /([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}/
  ,    !     ,     ip    ,     

【  】       ,  gawk 4.0       {n,m}     ,        
--re-interval --posix  。
フィールドフィルタ用
awkは、あるフィールドをフィルタすることによって、正規表現の前の行をフィルタすることもできます. nフィールドが正則を満たしていることを示すフィルタnは、正則式の前にn番目のフィールドがあることを示します.nフィールドが正則を満たしていないことを示します.n番目のフィールドは0を使います. 行を選別してもいいです.0は全行を意味します.
eg 124は「:」で切断/etc/passwdし、ユーザー名の長さが4のユーザを選別する.
# awk --posix -F :  '$1~/^.{4}$/{print $1}' /etc/passwd
root
sync
halt
mail
uucp
dbus
vcsa
abrt
sshd

【  】       ,  gawk 4.0       ^$     ,        
--re-interval --posix  。
eg 124は「:」で切断/etc/passwdし、ユーザー名の長さが4未満のユーザを選別する.
# awk --posix -F :  '$1!~/^.{4}$/{print $1}' /etc/passwd
bin
daemon
adm
lp
shutdown
operator
games
gopher
ftp
nobody
usbmuxd
rtkit
//         

【  】       ,  gawk 4.0       ^$     ,        
--re-interval --posix  。
式に使う
正規表現は、戻り値がtrue/falseである表現で、同じように~!~マッチングが成功したらtrueに戻ります.
eg 124処理/etc/passwd適合行数は20余りである.
# awk --posix -F :  '{if(NR ~ /^[2][0-9]$/)print NR,$1}' /etc/passwd
20 avahi-autoipd
21 abrt
22 haldaemon
23 gdm
24 saslauth
25 postfix
26 ntp
27 apache
28 pulse
29 sshd

【  】 NR       ,          /^[2][0-9]$/,     NR,     
もっと素晴らしい見たいです.【夢が恋しくなります.】