grepで単語単位で検索(“is”は対象とするが”this”は対象にしたくない)

Bash

はじめに

英単語一覧データが CSV ファイルとして提供されている場合に "is" を検索したいが、 "this" や "English" は対象から外したい、
といったことを grep コマンドで実現する方法です。

検証環境

$ uname -moi
x86_64 MacBookPro11,4 Darwin

$ bash -version | head -n 1
GNU bash, バージョン 5.0.7(1)-release (x86_64-apple-darwin18.5.0)

検索対象の英文サンプルを用意

今回処理させたい英文のサンプルを用意します。

cat <<'EOF' > sartre.txt
Man is condemned to be free.
Because once thrown into the world,
he is responsible for everything he does.
EOF

実存主義思想で有名なサルトルの言葉です。
余談ですが『存在と無』という書籍では「人間は自由という刑に処せられている」 という思想を主張しているように、自由(自分で決められること)は責任を伴います。

上記の英文に対して、 to とう文字で検索してみることにします。

普通に grep コマンドを利用した場合

普通に grep to してみます。

$ grep 'to' sartre.txt
Man is condemned to be free.
Because once thrown into the world,

本来調べたかった "to" という文字以外に、 "into" という文字も見つかってしまいます。

grep -w コマンドを利用した場合

grep コマンドに -w オプションを付けて実行してみます。

$ grep -w 'to' sartre.txt
Man is condemned to be free.

grep -w コマンドとはなに?

grep -w コマンドとは何でしょう?

このコマンドは、指定された文字列が「単語」として含まれている場合のみ出力します。
ここでいう「単語」は、英数字とアンダースコア(_)から構成される文字列のことです。

grep -w ls で検索した場合を例に上げます。

抽出できる文字列は以下の通りです。

  • ls
  • ls-remote ( - が区切り文字扱いとなる )
  • ls.txt ( . が区切り文字扱いとなる )

抽出できない文字は以下のとおりです。

  • lsof
  • false
  • tools
  • ls_outout.txt ( _ は区切り文字として認識されない )

CSVを絞り込む際に便利

便利な例として、CSVを絞り込む場合に有効です。

以下のようなCSVを用意します。

$ cat <<'EOF' > abc.txt
1,aa,bbb
2,bb,@@@
3,cc,bb
EOF

カラムのどこかに bb を含む行を抽出する場合、普通に抽出するとすべての行が抽出されてしまいます。

$ grep bb abc.txt
1,aa,bbb
2,bb,@@@
3,cc,bb

grep ',bb,' だと3行目が抽出できません。

$ grep ',bb,' abc.txt
2,bb,@@@

grep -w を使えば想定通りの結果が得られます。

$ grep -w bb abc.txt
2,bb,@@@
3,cc,bb

ひとこと

正規表現と組み合わせて利用することもできますが、多くのケースでは固定文字列で検索することになるでしょう。
-F オプションを付与して正規表現を利用しないようにすることで、高速化が図れます。

Bash