AWK: シェル変数を awk に渡す

AWK: シェル変数を awk に渡す

合格しようとしています。変えるシェルスクリプトからテーブルのパターン認識サブセットまでの引数の数。これまでに試したことは次のとおりです。

ファイル "infile":

    ID,GROUP
    1,GROUP2    
    2,GROUP2    
    3,GROUP4    
    4,GROUP4    
    5,GROUP5    
    6,GROUP5    
    7,GROUP23   
    8,GROUP23   
    9,GROUP23   

ファイルのサブセット.sh:

    #!/bin/sh
    rm -f outfile_$week

    week = $1
    shift

    for TOKEN in "$@"
    do

    echo "adding records for" $TOKEN

    awk -F "," -v group = $TOKEN '{ if(FNR > 2 && $2 ~/group/){print $0} }' infile >> outfile_$week
    done

また、group = "$TOKEN"、"group = $TOKEN"を試してから、両方とも一重引用符で試しました。私は次のように送信します。

    sh subset.sh 061314 GROUP2 GROUP23

エラーメッセージはほとんど表示されません。

    Usage: awk [-F fs][-v Assignment][-f Progfile|Program][Assignment|File] ...

助けてくれてありがとう。ありがとうございます!

編集:私は走ってみました

    awk -F "," -v group ="GROUP1" '{ if(FNR > 2 && $2 ~/group/){print $0} }' infile

役に立たない...(上記と同じエラー)これが起こる理由を知っている人はいますか?

答え1

次のように書く必要があります。

-v group="$TOKEN"

代わり-v group = $TOKENに構文エラーが発生しますawk

答え2

あなたがしたいと思います:

awk -F, '
  BEGIN {
    for (i = 1; i < ARGC; i++) group[ARGV[i]]
    ARGC=0
  }
  NR >= 2 && $2 in group' "$@" < infile

または、引数を2番目の列に一致する正規表現として扱いたい場合:

awk -F, '
  BEGIN {
    for (i = 1; i < ARGC; i++) group[ARGV[i]]
    ARGC=0
  }
  NR >= 2 {
    for (i in group) if ($2 ~ i) {print; next}
  }' "$@" < infile

答え3

直面している即時の問題は等号周辺の空白です。このオプションの引数は-v代入でなければなりません。 awkは引数-v、スクリプト(=)、ファイル名(値TOKEN、スクリプト、ファイル名)を確認します。

シェルスクリプトで同様の間違いを犯しました。week = $1でなければなりませんweek="$1"

さて、コマンドの置き換えには常に二重引用符を使用してください。。たとえば、TOKENisの場合、*現在のディレクトリのファイルのリストに置き換えられます。

awk -v "group=$TOKEN"

ただし、awkは割り当ての右側をawk構文のリテラルとして扱うため、group値をに設定しません。TOKENたとえば、値がTOKEN7文字の文字列の場合、foo\barawk変数はgroup6文字の文字列に設定されますfoo␈ar。ここで、バックスペース文字は(バイト値8)です。

変数をawkスクリプトに渡す簡単な方法は、変数を環境にエクスポートして配列を通して使用することですENVIRON

groupまた、awkスクリプトのどこでもこの変数を使用しません。正規表現は、/group/5文字の文字列を含むすべての文字列と一致しますgroup。フィールドが値とまったく同じであることを確認するにはgroup(たとえば、値がある場合はTOKEN含まGROUP2れるフィールドがGROUP24一致しない)、等しい演算子を使用します==

  export TOKEN
  awk -F "," '{ if (FNR > 2 && $2 == ENVIRON["TOKEN"]){print $0} }' infile >> outfile_$week

完全なスクリプトは次のとおりです。 awkの条件付きジョブ構文(print $0デフォルトであるため、ここではジョブは省略されています)を使用し、毎回出力ファイルを開くのを防ぐために、さらに単純化されています。

#!/bin/sh
week="$1"
shift
for TOKEN in "$@"
do
  echo "adding records for" $TOKEN
  awk -F "," 'FNR > 2 && $2 == ENVIRON["TOKEN"]' infile 
done >"outfile_$week"

バラよりStefan Chazerasの答えawkを使用する高度な方法では、入力ファイルを複数回処理する必要はありません。

関連情報