awk - 同じ行の直接パターンの後に一度交換してください!

awk - 同じ行の直接パターンの後に一度交換してください!

1.5MBファイルがあります。
1行には約160,000文字があります。
この行では、PATTERNの直後に「false」を「true」に一度変更するだけです。

awkの後、最初の発生のみが変更されます。
ただし、「PATTERN」以降は一度だけ変更してください。

awk '/PATTERN.*false/ {sub("false", "true")} {print}' file

私たちのファイルは次のとおりです。

...
colorA is false colorB is false PATTERN is false colorC is false colorD is false
...

ファイルには以下が必要です。

...
colorA is false colorB is false PATTERN is true colorC is false colorD is false
...

必要に応じてawkコマンドをどのように配置しますか?

よろしくお願いします!

ベストアンサー1

「false」と一致しない最短文字列に一致する正規表現を作成することは理論的に可能ですが、難しいです。他のさまざまな言語にはselect-shortest構文がありますが、awkはそのうちの1つではありません。

したがって、難しい表現を作成したくないと仮定すると、3つのアプローチがあります。

  1. 入力を「false」という単語に分割し、フィールドを繰り返して、現在のフィールドがパターンと一致する場合は「true」の後に印刷し、それ以外の場合は「false」の後に印刷できます。
  2. トリックを使用して、「false」のすべての項目をcontrol-aなどの未使用の単一文字に変換できます。これにより、正規表現は、最も短いモード制御で終わるものと一致するように[^\001]*\001と言えるように書くのは簡単です。 -ㅏ。
  3. フィールドを繰り返し、現在のフィールドがスキーマの場合はフラグを設定し、「false」、フラグが設定されている場合は「true」に変更し、フラグをリセットします。

方法3の場合。

#!/usr/bin/awk

/PATTERN.*false/ {
        for(i=1;i<=NF;i++) {
                if ($i ~ /PATTERN/) flag=1;
                if ($i == "false" && flag==1) {
                        $i="true"
                        flag=0
                }
        }
}
{print}

これにより、入力の空白が縮小されます。

おすすめ記事