
私は合格しようとしています変数シェル スクリプトからテーブルのパターン認識サブセットへの引数の数。これまでの私の試みは次のとおりです。
ファイル「infile」:
ID,GROUP
1,GROUP2
2,GROUP2
3,GROUP4
4,GROUP4
5,GROUP5
6,GROUP5
7,GROUP23
8,GROUP23
9,GROUP23
ファイル subset.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"
。
ところで、コマンド置換は常に二重引用符で囲むたとえば、TOKEN
が の場合*
、現在のディレクトリ内のファイルのリストに置き換えられます。
awk -v "group=$TOKEN"
ただし、awk は代入の右側を awk 構文のリテラルとして扱うため、group
の値は設定されません。たとえば、 の値が 7 文字の文字列 である場合、awk 変数は6 文字の文字列 に設定されます。ここで、はバックスペース文字 (バイト値 8) です。TOKEN
TOKEN
foo\bar
group
foo␈ar
␈
変数を 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
print $0
以下は、awk の条件アクション構文 (ここではアクションはデフォルトなので省略) を使用し、毎回出力ファイルを開かないようにするために、さらに少し簡略化されたスクリプト全体です。
#!/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"
見るステファン・シャゼラスの回答入力ファイルを複数回処理する必要がない、より高度な awk の使用方法。