awkで正規表現を使用して、最初のフィールドに4つの文字しかない行を印刷しますか?

awkで正規表現を使用して、最初のフィールドに4つの文字しかない行を印刷しますか?
John Goldenrod:(916) 348-4278:250:100:175

Chet Main:(510) 548-5258:50:95:135

Tom Savage:(408) 926-3456:250:168:200

Elizabeth Stachelin:(916) 440-1763:175:75:300

出力には、4文字の名前(john、chet)のみを含む行を含める必要があります。

awk '$1 ~ /[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]" "/ {print}' file

これは私には適していないようです。 awk関数を使用せずにこれを実行できますか?

答え1

awkのフィールドはデフォルトでは" "で区切ります。これは$1空白がないことを意味するので、正しい正規表現は次$1のようになります。

awk '$1 ~ /^[a-zA-Z0-9]{4}$/ {print}' file

元の方法を維持するには、$0次のように使用することもできます。

awk '$0 ~ /^[a-zA-Z0-9]{4}\s/ {print}' file

\w簡単にするために、単語文字を明示的に定義する代わりに、次のように使用することもできます。

awk '$0 ~ /^\w{4}\s/ {print}' file

スペースだけを一致させ、他のものを一致させたくない場合は、「」(引用符を除く)にTAB置き換えてください。\s

元のアプローチのもう一つの問題は、アンカーポイントがないことです。指定しなかったため、パターンはどこにも現れません。つまり、パターンが と^一致します。$Elizabeth Stachelinbeth

答え2

AWKでは、正規表現を次のように使用できます。模様AWKスクリプトでよく見られるものと同じですBEGINEND単純化されたコードは次のとおりです。

awk '/^[[:alnum:]]{4}\>/'

これはあなたの要件を満たすために必要なすべてです。あなたは必要ありません行動{print}パターンマッチング時にデフォルトのジョブとしてレコード全体、つまり行全体を印刷します。

[:alnum:][a-zA-Z0-9]ロケールに応じて基本的に同義語です。使用することもできます\w。ただし、_underscoreの略語であるunderscoreも含まれています[[:alnum:]_]

awk '/^\w{4}\>/'

\>単語の終わりを一致させます。これにより、John:(###)...フルネームを含まないレコードがある場合に文字列を正しく一致させることができます。

AWKについてお問い合わせいただきましたが、sedこの場合、AWKよりもほぼ2倍速い速度で実行されるAWKを使用することをお勧めします。

sed -n '/^[[:alnum:]]\{4\}\b/p'

\bはい\>または\<AWKです。 500,000ラインをテストし、100,000ラインをマッチングしましたが、AWKは約1.7秒かかり、sedは0.9秒しかかかりませんでした。しかし、テストケースは極端であり、これはただの難しい提案です。

私も読んでman 7 regexman awk勧めしますinfo awk

答え3

最初のフィールドはで、$1長さはlength($1)そのためです。

awk 'length($1) == 4 {print}'

それとももっと簡単に

awk 'length($1) == 4'

あなたが書いた内容がうまくいかない理由は2つあります。まず" "、正規表現に追加のエントリがあるため、フィールドに二重引用符、スペース、二重引用符を含める必要があります。この問題を解決すると、/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]/4つ以上のASCII文字または数字を含むフィールドと一致しますが、それ以上を含めることができるので、一致しますが一致しElizabethませJohnTom。始めと終わりに固定された正規表現を書くことができますが、欲しい/^[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]$/もの長さフィールドの場合、これを作成するだけです。

関連情報