優雅なShellスクリプトの作成方法(3)

7796 ワード

優雅なShellスクリプトの作成方法(3)
  • 概要
  • awk構文
  • awk内蔵変数
  • awk内蔵関数
  • awk実践
  • awkファイル関連
  • awkファイル分割
  • まとめ
  • 概要
    awkはshellスクリプトのテキスト処理が不思議で、Java、C、C++などの高度な言語のようにサービスタイプのアプリケーションを開発していませんが、ファイルの処理が得意です.このブログは主に自分のこれまでの仕事の中でawkを使っていたことをまとめています.awkの文法を全面的に紹介することはありません.AWKをもっと深く理解していれば、awkの本「awkとsed」をお勧めします.しかし、仕事で使うawkのいくつかの機能について紹介します.くだらないことは言わないで、本題に入りましょう.
    awk構文
    awkは実はファイルを1行1行の遍歴処理で、各行のコードはテキストの中の1行の記録を処理して、読み取る順序です.
  • ファイルのパラメータの取り込み順で読み込む
  • .
  • 各ファイルは、1行目から最後以降の順に
  • を読み出す.
    AWKプログラムの基本的な構成部分は、次のとおりです.
  • BEGIN:Javaのクラスのコンストラクション関数に相当し、プログラムは最初の実行ブロック
  • を起動する.
  • 本体部分:本体部分は2つの中括弧で囲まれており、1つのawkプログラムには複数の中括弧があり、複数の中括弧で囲まれると便利なパラメータファイルの内容が繰り返されて処理されます(この機能の半分は少ない).
      awk [option] 'BEGIN{
      }
      [partition]{
      }END{
      }'       
    awk -f awk           

    option、プロジェクトで使用される選択肢は-f-F-vです.-fオプションはawkのプログラムを1つのファイルに書き、-fパラメータでファイルの内容をawkスクリプトプログラムとします.
    $ cat test.data
    1,hello,awk
    2,hello,shell
    $ cat test.awk
    BEGIN{ print "begin" }
    {
      print $0
    }
    END { print "end" }
    $ awk -f test.awk test.data 
    begin
    1,hello,awk
    2,hello,shell
    end

    -F解析ファイルの区切り文字を作成し、複数の文字を使用できます.デフォルトの区切り文字はスペースとタブです.FS内蔵変数で実現することもできます.
    $ awk -F"," '{print $2}' test.data
    hello
    hello

    -v、shellスクリプトの変数をawkに転送できます.
    $ shellVar="awk"
    $ awk -F"," -v shellVar=$shellVar '{print shellVar}' test.data
    awk
    awk
    $ awk -F"," -v shellVar=$shellVar '$3==shellVar{print $0}' test.data
    1,hello,awk

    awk内蔵変数
    変数#ヘンスウ#
    意味
    ARGC
    コマンドラインパラメータ個数
    ARGV
    コマンドラインパラメータ配列
    FILENAME
    現在の入力ファイル名
    FNR
    現在のファイルのレコード番号
    FS
    フィールド区切り記号を入力します.デフォルトはスペースです.
    RS
    レコード区切りの入力
    NF
    現在のレコード内のドメイン数
    NR
    これまでの記録数
    OFS
    ドメイン区切り文字の出力
    ORS
    出力レコード区切り
    awk内蔵関数
  • split(String,A,[Ere])Stringパラメータで指定されたパラメータを配列要素A[1],A[2],.,に分割する.A[n]は、n変数の値を返します.この分割は、Ereパラメータによって指定された拡張正規表現によって行うか、または現在のフィールド区切り記号(FS特殊変数)によって行うことができます(Ereパラメータが与えられていない場合).コンテキストによって指定された要素に数値値がある必要がある場合を除き、A配列の要素は文字列値で作成されます.
  •  $ awk '{
        split($0,a,",");
        print a[1],a[2],a[3]
     }' test.data
    1 hello awk
    2 hello shell
    
    #       a,split        1  。       OFS         
    $ awk 'BEGIN {OFS="~"}{
        split($0,a,",");
        print a[1],a[2],a[3]
     }' test.data
    1~hello~awk
    2~hello~shell
  • gsub(Ere,Repl,[In])は、正規表現のすべての特定の値が置換されている点を除いて、sub関数と全く同じように実行される.
  • sub(Ere,Repl,[In])は、Inパラメータによって指定された文字列のうち、Ereパラメータによって指定された拡張正規表現の最初の具体的な値を、Replパラメータによって指定された文字列に置き換えます.sub関数は置換数を返します.Replパラメータで指定された文字列に表示される&(および記号)は、Ereパラメータで指定された拡張正規表現と一致するInパラメータで指定された文字列に置き換えられます.Inパラメータが指定されていない場合、デフォルト値はレコード全体($0レコード変数)です.
  • .
     $  awk -F"," '{a=$3; gsub("awk","      ", $3); print a, $3}' test.data
    awk       
    shell shell
  • match(String,Ere)Stringパラメータで指定された文字列(Ereパラメータで指定された拡張正規表現が表示されます)で位置(文字形式)を返し、1から番号を付けます.または、Ereパラメータが表示されない場合は0を返します.(ゼロ).RSTART特殊変数は戻り値に設定されます.RLENGTH特殊変数は一致する文字列の長さに設定されます.または一致が見つからない場合は-1(負)に設定されます.
  •   $  awk -F"," '{match($3,'/^[a-z]{2}k$/'); print RSTART, RLENGTH}' test.data  
    1 3
    0 -1
    #        ,                    
    $ awk '{
    value=$1
    while(match(value,/\w+,/) > 0) {
      print substr(value,RSTART,RLENGTH-1);
      value=substr(value,RLENGTH+1);
    } print value
    }' test.data
    1
    hello
    awk
    2
    hello
    shell
  • tolower(String)は、Stringパラメータで指定された文字列を返します.文字列の各大文字は小文字に変更されます.大文字と小文字のマッピングは、現在の言語環境のLC_CTYPEカテゴリ定義.
  • toupper(String)は、Stringパラメータで指定された文字列を返します.文字列の各小文字は大文字に変更されます.大文字と小文字のマッピングは、現在の言語環境のLC_CTYPEカテゴリ定義.

  • awk実践
    awkファイル関連付け
    awkはSQLのように、2つと複数のファイルを関連付けることができます.次の2つのファイルがあります.
    $ cat test2.data 
    1,    
    $ cat test.data  
    1,hello,awk
    2,hello,shell
    
    # test.data    test2.data
    $ awk -F"," '{if (FILENAME=="test2.data") { a[$1]=$2 } else {
      print $0, a[$1]
    }}' test2.data test.data
    1,hello,awk     
    2,hello,shell

    awkファイル分割
    現実の作業では、1つのインタフェースファイルで、各行に1つ以上のフィールドが記録されている配列が必要であり、配列を1つのストライプに分割する記録が必要です.
    $ cat test3.data
    1,test1,  11&  12
    2,test2,  21&  22
    #       
    $ awk -F"," '{
    split($3,a,"&");  #            a  
    for (i in a) {
      print $1,$2,a[i]
    }
    }' test3.data
    1 test1   11
    1 test1   12
    2 test2   21
    2 test2   22
    

    まとめ
    本文は主に過去のいくつかの仕事でshellスクリプトに使用されたawkコマンドについてまとめ,まとめた内容はawkの氷山の一角に属する.awkがあなたを引き付けると、以下のawkを系統的に理解することができます.「awkとsed」という本を読むか、linuxシステムでmanコマンドを使用してawkのヘルプドキュメントを取得することをお勧めします.