web-dev-qa-db-ja.com

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関数を使用せずにそれを行うことはできますか?.

3
munish

Awkのフィールドは、デフォルトでは「」で区切られます。これは、$1にスペースが含まれていないことを意味します。したがって、$1の正しい正規表現は次のとおりです。

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

元のアプローチを維持したい場合は、代わりに$0を使用することもできます。

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

物事を単純化するために、Word文字を明示的に定義する代わりに\wを使用することもできます。

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

スペースのみを一致させ、TABのようなものは一致させたくない場合は、\sを ""(引用符なし)に置き換える必要があります。

元のアプローチのもう1つの問題は、アンカーがないことです。 ^$も指定しなかったため、パターンはどこでも発生する可能性があります。つまり、パターンはElizabeth Stachelinbethで一致します。

6
Ulrich Dangel

AWKでは、正規表現をpatternとして使用できます。たとえば、AWKスクリプトでよく見られるBEGINまたはENDのようになります。簡略化されたコードは次のようになります

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

これはあなたがあなたのニーズを満たすために必要なすべてです。 actionは必要ありません。パッテンが一致した場合のデフォルトのアクションは_{print}_で、レコード全体、つまり行全体が出力されます。

_[:alnum:]_は、ロケールに応じて、基本的に_[a-zA-Z0-9]_の同義語です。 _\w_を使用することもできます。アンダースコア___も含まれているだけで、_[[:alnum:]_]_の省略形です。

_awk '/^\w{4}\>/'
_

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

AWKを求めていますが、sedを使用することをお勧めしますが、次の場合、AWKのほぼ2倍の速度で実行されます。

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

_\b_はAWKでは_\>_または_\<_です。私は500K回線でテストし、100K回線が一致し、AWKは約1.7秒かかり、sedは0.9秒しかかかりませんでした。しかし、テストケースは極端であり、それは単なるちょっとした提案です。

また、_man 7 regex_、_man awk_、_info awk_もお読みになることをお勧めします。

3
livibetter

最初のフィールドは_$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およびJohnに一致します。 、ただしTomではありません。_/^[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]$/_を記述して正規表現を開始と終了に固定できますが、必要なのがフィールドのlengthである場合は、それを記述してください。