awkで範囲モードの範囲を制限する方法はありますか?

awkで範囲モードの範囲を制限する方法はありますか?

私は以下からインスピレーションを得て、ファイルセット内のすべてのSQL文をawk見つけるために範囲パターンを使用しようとしています。selectこのstackoverflowの答え

awkマニュアルから:

表現の形をpattern1, pattern2指す。範囲モード。一致するレコードで始まり、pattern1一致するレコードを pattern2含むすべての入力レコードを一致させます。

私の最初の試みは

awk '/select/,/from/' *

この場合、*さまざまなファイルがたくさん表示されます。

これにより、selectHTMLタグに誤ったヒットが返されたため、次のようにコマンドを改善しました。

awk '/[^<]select[^>]/,/from/' *

これにより、ほとんどのクリックが削除されるようです。

ただし、コメントに「select」という単語が表示されるため、まだいくつかの誤ったヒットが発生し、これらのヒットは、「from」の最後のヒットまたはファイルの終わりより前の各ヒットから多くのラインノイズにつながります。私が望むのは、「select」と「from」の間に10行以上がある場合、範囲パターンが一致を登録しないことです。

pattern1私の質問は:一致と一致の間の行数が指定されたしきい値をpattern2超えると、範囲パターンが一致しないようにすることはできますか?では、どうすれば達成できますか?

ベストアンサー1

スコープモードは便利ですが、柔軟性はありません。これを使用しないで、代わりに変数間または変数間の状態を維持してください。 awkスクリプト/select/,/from/は次のとおりです。

/select/ {printing = 1}
printing {print}
/from/ {printing = 0}

範囲を複数の行に制限するには、表示された行のカウンタを保持し、表示するかどうかを判断するまで出力を累積します。

/select/ {select_text = $0; select_line_count = 1;}
select_line_count {select_text = select_text "\n" $0}
/from/ {if (select_line_count <= 10) {print select_text; print}
        select_line_count = 0}

select行の先頭(スペースを除く)に含める必要があり、その後にスペースが続くようにパターンを最適化する必要があります。/^[\t ]*select($|[\t ])/

おすすめ記事