2012年8月9日木曜日

シェルスクリプトでスペース区切りのメアドリストから特定ドメインのメアドだけ抽出してコンマとスペース区切りに変換するには?

シェルスクリプトでスペース区切りのメアドリストから特定ドメインのメアドを抽出してコンマとスペース区切りに変換するにはどうしたらいいだろう?

例えばこんなメアドリスト。

a@xxx.com b@yyy.com c@xxx.com d@zzz.com

このリストから、xxx.comドメインのメアドを抽出してこんな感じにしたい。

a@xxx.com, c@xxx.com

sedを使って「xxx.com以外のメアドを削除」とすればできそうだけど、sedは文字列の否定条件ができないらしい。そこでgrepを使って抽出することにした。

grepで抽出するにはそれぞれのメアドを行にしなければならないので、まずsedを使ってスペースを「, \n」に置換する。「\n」を入れることで改行できる。

# echo "a@xxx.com b@yyy.com c@xxx.com d@zzz.com" | sed -e "s/ /, \n/g"
a@xxx.com,
b@yyy.com,
c@xxx.com,
d@zzz.com

さらに、この出力にxxx.comを条件にしてgrepをかける。

# echo "a@xxx.com b@yyy.com c@xxx.com d@zzz.com" | sed -e "s/ /, \n/g" | grep xxx.com
a@xxx.com,
c@xxx.com,

複数行にしてしまったので、trコマンドを使って一行に戻す。trで改行を削除する感じで。

# echo "a@xxx.com b@yyy.com c@xxx.com d@zzz.com" | sed -e "s/ /, \n/g" | grep xxx.com | tr -d "\n"
a@xxx.com, c@xxx.com,

はじめはsedで「sed -e "s/\n//g"」として改行を削除すればできると思ったけど、できなかったのでtrコマンドを使った。

行末に「, 」が付く場合があるので、これをsedを使って削除する。行末($で表現)の「, 」を削除する感じ。

# echo "a@xxx.com b@yyy.com c@xxx.com d@zzz.com" | sed -e "s/ /, \n/g" | grep xxx.com | tr -d "\n" | sed -e "s/, $//g"
a@xxx.com, c@xxx.com

これでやっと欲しかった出力結果を得られた。


Javaやなんかで同じ事をするならすぐにコードを思いつくけど、シェルではメソッドの組み合わせではなくて、コマンドの組み合わせのパズルで問題を解決していかなければならないんだなぁと改めて感じた。

しかし、一度パスルが解けてしまえば、その力は絶大だ。