Bashのawkパターンと一致する変数の定義

Bashのawkパターンと一致する変数の定義

X は {0,40,80,...,200} の「time: X」テキストの後に続く 100 行を取得しようとします。これが私が今まで持っているものです:

#!/bin/bash
start=1
end=5
for i in $(seq $start $end);do 
  j=$(($i*40))
  awk '/time: $j/{for(i=1;i<=100;i++}{getline;print}}' file > fileX-$j.txt
done 

しかし、これはうまくいかないようです。私の質問は特に変数$ jに関するもので、 '/time: ...'の後に変数を定義する方法についてです。

たとえば、「file」というファイルがあります。

time: 1
1 2 3 
1 33 1 
2 31 4
time: 40
2 1 3 
9 8 77
1 3 4

この場合、2つの別々のファイルを作成したいと思います。

1 2 3 
1 33 1 
2 31 4

2番目は次のとおりです。

1 2 3 
1 33 1 
2 31 4

mazsが述べたように、$ jを変数として渡そうとしましたが、まだ空のファイルが提供されています。私がする方法は次のとおりです。

awk -v jj=$j '/time: jj/{for(i=1;i<3;i++){getline;print}}' file > fileX-$j.txt

答え1

2つの質問があります。 1つ目は、シェルが$j一重引用符内で拡張されないことです。つまり、変数値ではなく'$j'文字列が欲しいとシェルに通知します。$jj

この場合、値には数字のみが含まれるため、単一引用符の外に入れることができます。

awk '/time: '"$j"'/{for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt

j値に正規表現特殊文字(.など)が含まれている場合、その*文字はそのように解釈されます。例えば

j='2*3'
awk '/foo '"$j"' bar/'

スクリプトは代わりに、などfoo 3 barfoo 23 bar含む行を印刷します。値に awk がある場合、たとえば正規表現のマッチ構造の終わりが表示されます。foo 223 barfoo 2*3 bar/

j='2/3'
awk '/foo '"$j"' bar/'

トークンシーケンス/foo 2/、、3が構文上正しくないとawkで文句を言いますbar/

コマンドラインオプションを使用して、awkの変数を定義できます-v

j='a\tb'
awk -v j="$j" '{print j}'

この値のペアはバックスラッシュ拡張を実行しますj。たとえば、上記のコードスニペットは各行をa↦bタブ文字に置き換えます。

ただし、awkは内部変数を拡張しないため、これはあなたの場合には直接適用されません/…/。これは変数の値ではなく/foo/文字列と一致します。正規表現の一致に変数を使用するには、次の関数を使用する必要があります。foofoomatch

awk -v j="$j" 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt

これはjバックスラッシュを含まない値に適用されます。たとえば、にj設定すると、などa/b*cの行に一致します。に設定すると、後ろにスペースとタブが含まれる行と一致します。time: a/ctime: a/bcj\ttime:

シェル変数の値をawkに渡すには、値が何であれ環境を渡します。

export j
awk 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt

または、j残りのスクリプトが進行中に環境に閉じ込められないようにするには、次の手順を実行します。

j="$j" awk 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt

正規表現の代わりにリテラル文字列を取得するには、代わりにindexこの関数を使用できますmatch

j='a*b'
awk 'index($0, "time: "+j)'

印刷にはが含まれていますtime: a*b

答え2

$ jシェル変数をawkに渡す必要があります。

awk -v jj="$j" '...'

引数にバックスラッシュ拡張が適用されるため、変数の値にバックスラッシュが含まれていないとしますawk -v

関連情報