awkコマンドはスペースとタブ両方を区切り文字と判断することを忘れがち

SESエンジニアの日常
SESエンジニアの日常

現場あるあるシリーズ。
(あまりあってはいけないけれど、)スペース区切りのファイル(.ssv)にタブが使われている時がある。

こんなサンプルを用意してみました。

$ cat sample.ssv 
001 佐藤 野球部	サッカー部 sato@sample.com
002 山田 テニス部 yamada@sample.com
003 木村 生徒会	陸上部 kimura@sample.com

一見、フツーのスペース区切りのファイルですが、スペースとタブが混在するというトラップが含まれています。
所属部が複数ある場合、それがタブで区切られているんですね。
「001(スペース)佐藤(スペース)野球部(タブ)サッカー部(スペース)sato@sample.com」
「002(スペース)山田(スペース)テニス部(スペース)yamada@sample.com」
「003(スペース)木村(スペース)生徒会(タブ)陸上部(スペース)kimura@sample.com」

awkコマンドでスペース区切りでフィールド抽出した時の挙動

このファイルから名前とメールアドレスを抜き出したリストを作成しておいて。
フィールドは”学籍番号” “名前” “所属部” “メールアドレス”だから、よろしく。

分かりました。2列目と4列目を抜き出せばいいんですね。

今回のサンプルのような単純な物でしたらExcelでスペース区切りでデータを読み込み、必要な列のみ抽出する方法でもいいですが、レコード数が多かったり、ファイルサイズが大きかったりするとExcelでは処理が重すぎてイライラが募ってしまいます。

今回の仕事を任されたA君、第3フィールドにタブが使われていることなど知るはずもなく、awkコマンドで第2フィールドと第4フィールド抽出しまました。

$ cat sample.ssv | awk '{print $2,$4}'
佐藤 サッカー部
山田 yamada@sample.com
木村 陸上部

お、おかしい、、佐藤さん木村さんのメールアドレスが取れてないぞ

ここでA君、第3フィールドにタブが含まれていることに気づきます。
それならば、区切り文字にスペースを明示してやればいいのか、とやってみますが、
結果はさっきと同じになりました。

$ cat sample.ssv | awk -F " " '{print $2,$4}'
佐藤 サッカー部
山田 yamada@sample.com
木村 陸上部

区切り文字を指定しないときは、スペースとタブ両方を区切り文字と判断しますが、区切り文字にスペースを指定しても、スペースとタブ両方を区切り文字としてしまいます。
awkコマンドの挙動で注意するべきところです。

スペースとタブが混在するレコードをスペース区切りで抽出する

こんなとき、みなさんどうしますか?

私はというと、あまりいい方法が思い浮かばなかったので、力技でやっちゃいました。

 ①区切り文字「スペース」を別の文字「@@」に置き換える
  (ファイル内に文字列「@@」が存在しないことは確認した上で)
 ②「@@」を区切り文字として、awkで第2フィールド、第4フィールドを抽出する

$ cat sample.ssv |sed 's/ /@@/g' | awk -F "@@" '{print $2,$4}'
佐藤 sato@sample.com
山田 yamada@sample.com
木村 kimura@sample.com

はい。こんな感じで、名前とメールアドレスを抽出することができました。

awkコマンドの基本操作についてはここにまとめました。

コメント

タイトルとURLをコピーしました