awk
コマンドラインからユーザー入力を読み込み、変数として保存するスクリプトを作成しようとしています。
コマンドラインでコンパイルして実行すると
./myawk.awk -v ID=4 text.sql
IDは4に設定された変数になります。しかし、私のスクリプトで提供されている入力テストケースは
./myawk.awk ID=4 text.sql
このスクリプトの究極の目標は、次に始まるIDを取得することです。
-- ID
そして、次の行を印刷します。私が今まで持っているのは
#!/bin/awk -f
{
if ($1 ~/--/ && $2 ~/^ID/){
x = NR+1
}
while (NR <= x){
print $0
}
}
-v
その行を変更したり、その前に追加せずに変数IDをどのように読み取ることができますか?awk
現在のスクリプトに関するいくつかの提案があるかもしれません。
ベストアンサー1
変数の割り当てがスクリプトのコマンドラインでファイルオペランドとして提供されている場合、ファイルawk
オペランドを使用するときにそのポイントに達すると割り当てが実行されます。awk
例:
awk -f script.awk a=1 file1 file2 a=2 file3 a=3 file4
ここでawk
変数は読み取り前にa
設定されます。この変数は、ファイルが読み込まれるまでこの値を保持します(プログラムによって変更されない限り)。次に、等に設定します。1
file1
awk
file2
2
これは、コマンドラインが変数をID
読み取る前に変数を正しく設定していることを意味します。4
text.sql
-v ID=4
これとこれの違いは、ID
どのブロックにも設定されないことですBEGIN
。-v ID=4
コレクションを使用してID
、4
それ〜するチャンクとして利用可能ですBEGIN
。
コードの他の問題はID
リテラルとして使用することです。ひも存在する
if ($1 ~/--/ && $2 ~/^ID/){
つまり、2番目のフィールドが文字列で始まるかどうかをテストしますID
。
while
ファイルの行を繰り返すようです。 1行ずつ読み取るループがawk
動作モードに組み込まれています。珍しい明確にする必要があります。
代わりに、
$1 == "--" && $2 == ID { getline; print }
これは、文字列比較(正規表現一致ではない)を使用して、現在の行でスペースで区切られた最初のフィールドが文字列であるか、--
2番目のフィールドが変数値であるかを確認しますID
。その場合は、次の入力行を読み、印刷します。
代わりに正規表現を使用するには
$0 ~ "^-- " ID "$" { getline; print }
これは、ダブルダッシュと単一のスペースで始まるすべての行と一致し、その後に値と行末ID
($
行末と一致)が続きます。一致する行の後の行が印刷されます。