【Linux入門】grepコマンドの基本を学ぶ

ファイル処理を行うにあたって、ファイルの中身を検索したい場面は頻繁に訪れます。そこで便利なコマンドがgrepコマンドです。

本稿ではgrepコマンドの基本から各種オプションまでを解説します。


 grepコマンドの用法

grepコマンドの基本的な使い方は以下のようになります。

 

$ grep 正規表現 ファイル名

 

(※「$ 」はコマンド受付中のマークです。既に表示されているので皆さんが入力する必要はありません)

正規表現というのは「いくつかの文字列を一つの特別な文字や形式で表す表現方法」と説明されます。ここでは難しく考えないで「検索したい文字」程度の意味に考えておいてください。

 

 grepコマンドを使ってみよう

それでは「tdhk.txt」というファイルに都道府県名のリストが書きこまれている場合を例に使い方を見ていきましょう!(ここではファイル名を「都道府県」になぞらえて “tdhk.txt” としていますが、実際にはどんな名前でも構いません)

実際にコマンドを試してみたい方のために都道府県名や県庁所在地名のリストを作りましたので、必要に応じてご活用下さい。

» 都道府県名のリスト

hokkaido
aomori
iwate
miyagi
akita
yamagata
fukushima
ibaraki
tochigi
gunma
saitama
chiba
tokyo
kanagawa
niigata
toyama
ishikawa
fukui
yamanashi
nagano
gifu
shizuoka
aichi
mie
shiga
kyoto
osaka
hyogo
nara
wakayama
tottori
shimane
okayama
hiroshima
yamaguchi
tokushima
kagawa
ehime
kochi
fukuoka
saga
nagasaki
kumamoto
oita
miyazaki
kagoshima
okinawa

» 閉じる

» 県庁所在地名のリスト

sapporo
aomori
morioka
sendai
akita
yamagata
fukushima
mito
utsunomiya
maebashi
saitama
chiba
shinjuku
yokohama
niigata
toyama
kanazawa
fukui
kofu
nagano
gifu
shizuoka
nagoya
tsu
otsu
kyouto
osaka
koube
nara
wakayama
tottori
matsue
okayama
hiroshima
yamaguchi
tokushima
takamatsu
matsuyama
kochi
fukuoka
saga
nagasaki
kumamoto
oita
miyazaki
kagoshima
naha

» 閉じる

» 都道府県名と県庁所在地名のリスト

hokkaido sapporo
aomori aomori
iwate morioka
miyagi sendai
akita akita
yamagata yamagata
fukushima fukushima
ibaraki mito
tochigi utsunomiya
gunma maebashi
saitama saitama
chiba chiba
tokyo shinjuku
kanagawa yokohama
niigata niigata
toyama toyama
ishikawa kanazawa
fukui fukui
yamanashi kofu
nagano nagano
gifu gifu
shizuoka shizuoka
aichi nagoya
mie tsu
shiga otsu
kyoto kyouto
osaka osaka
hyogo koube
nara nara
wakayama wakayama
tottori tottori
shimane matsue
okayama okayama
hiroshima hiroshima
yamaguchi yamaguchi
tokushima tokushima
kagawa takamatsu
ehime matsuyama
kochi kochi
fukuoka fukuoka
saga saga
nagasaki nagasaki
kumamoto kumamoto
oita oita
miyazaki miyazaki
kagoshima kagoshima
okinawa naha

» 閉じる

例えば、”kyoto” という単語が「tdhk.txt」というファイル内に存在するかどうかは次のように調べることができます。

 

$ grep kyoto tdhk.txt

 

これの結果はつぎのようになります。

 

kyoto

 

これを “kyoto” ではなく “kyouto” にした場合、何も表示されません(実際にやってみましょう)。

では、”kyo” で検索した場合はどうなるでしょうか?

 

$ grep kyo tdhk.txt

tokyo
kyoto

 

“kyo” という文字列を含む行が出力されました。

試しに “yama” で検索すると以下のようになります。

 

$ grep yama tdhk.txt

yamagata
toyama
yamanashi
wakayama
okayama
yamaguchi

 

このように、grepコマンドは該当する文字列があればそれを全て表示する、というコマンドであることがお分かり頂けたと思います。因みに、検索したい単語はシングルクォーテーション、またはダブルクォーテーションで囲んでもgrep可能です!

(ダブルクォーテーションを使った例)

$ grep "yama" tdhk.txt

 

●   ●   ●

Linuxを使うにあたって、grepで出てきた沢山の結果からさらに条件に合うものを抽出したい、といった場面に出くわすことがしばしばあります。こういう時はgrepコマンドを複数回使うことでほとんど解決します。

 

 grepコマンドで「and検索」

grepコマンドで絞り込んだ結果に対して、さらに条件を加えて検索したい場合はパイプラインを使います(BACK SPACEキーの隣りのキーの「|」という文字を「パイプ」といいます)。

パイプはコマンドの結果を次のコマンドに受け渡すという機能をもちます。grepの出力結果以外でもlsコマンドの結果に対して

 

$ ls | grep test.txt

 

のようにすればディレクトリ内のファイルを検索することもできます。この例だとlsコマンドの結果をさらにgrepするという操作になります。lsコマンドの結果をgrepするからといって、次のようには書けません。

(ダメな例)

$ grep test.txt ls

 

これだとlsというファイルもしくはディレクトリを検索することになってしまいます。

●   ●   ●

それでは、先ほどの “yama” の検索結果をさらに絞り込み、”u” という文字列を含むものだけを取り出してみましょう。

 

$ grep yama tdhk.txt | grep u

yamaguchi

 

無事、”yamaguchi” という文字列が得られました。これは “yama” という文字列を含み、かつ、”u” という文字列を含む行を抽出する、という「and検索」になっています。

2回目のgrepコマンドが同じ “tdhk.txt” というファイルを対象としていると考えて次のように書くと意図しない結果になります。

(ダメな例)

$ grep yama tdhk.txt | grep u tdhk.txt

fukushima
gunma
fukui
gifu
shizuoka
yamaguchi
tokushima
fukuoka
kumamoto

 

「grep yama tdhk.txt」のコマンドが無視されてしまいました。通常は

「grep 文字列 検索対象」

と書きますが、パイプで繋いだ場合は検索対象の部分が前置されることになります。これは英語の関係代名詞の用法で目的語が前置されている、というイメージに近いです。

●   ●   ●

この他、パイプラインを使わずに「ドット+アスタリスク」でand検索する方法もあります。

 

$ grep yama.*u tdhk.txt

yamaguchi

 

grepを2回使うよりもこちらの方がタイピングが簡単ですね!

因みに「&」に「かつ」という意味があることを知っている方なら「yama&u」や「yama&&u」でも検索できるのではないか、と思われるかもしれませんが、この場合の「&」はバックグラウンド処理の命令として認識されてしまいます。もしそうでなくとも「”yama” かつ “u” でもあるような文字列」(そんなものは存在しません)を検索しようとしますので、「”yama” という文字列を含み、かつ、”u” という文字列を含む行を抽出する」という操作にはなりません。

●   ●   ●

それでは “yama” という文字列を含むか、または、”u” という文字列を含むものを抽出する、という「or検索」をしたいときはどうすればよいのでしょうか?

 

 

 grepコマンドで「or検索」

大抵のコマンドには拡張的な機能として、「オプション」が整備されています。grepコマンドも例外ではなく、知っていると便利なものから、普段ほとんど使わないようなものまで、様々なオプションが用意されています。

» grepコマンドのオプション

●   ●   ●

usageを確認するために「grep –help」と打ち込んでみると、以下のようなオプションのリストが表示されます(環境によっては若干の違いがあるかもしれません)。

  -E, --extended-regexp     PATTERN is an extended regular expression (ERE)
  -F, --fixed-strings       PATTERN is a set of newline-separated fixed strings
  -G, --basic-regexp        PATTERN is a basic regular expression (BRE)
  -P, --perl-regexp         PATTERN is a Perl regular expression
  -e, --regexp=PATTERN      use PATTERN for matching
  -f, --file=FILE           obtain PATTERN from FILE
  -i, --ignore-case         ignore case distinctions
  -w, --word-regexp         force PATTERN to match only whole words
  -x, --line-regexp         force PATTERN to match only whole lines
  -z, --null-data           a data line ends in 0 byte, not newline

Miscellaneous:
  -s, --no-messages         suppress error messages
  -v, --invert-match        select non-matching lines
  -V, --version             print version information and exit
      --help                display this help and exit
      --mmap                ignored for backwards compatibility

Output control:
  -m, --max-count=NUM       stop after NUM matches
  -b, --byte-offset         print the byte offset with output lines
  -n, --line-number         print line number with output lines
      --line-buffered       flush output on every line
  -H, --with-filename       print the filename for each match
  -h, --no-filename         suppress the prefixing filename on output
      --label=LABEL         print LABEL as filename for standard input
  -o, --only-matching       show only the part of a line matching PATTERN
  -q, --quiet, --silent     suppress all normal output
      --binary-files=TYPE   assume that binary files are TYPE;
                            TYPE is `binary', `text', or `without-match'
  -a, --text                equivalent to --binary-files=text
  -I                        equivalent to --binary-files=without-match
  -d, --directories=ACTION  how to handle directories;
                            ACTION is `read', `recurse', or `skip'
  -D, --devices=ACTION      how to handle devices, FIFOs and sockets;
                            ACTION is `read' or `skip'
  -R, -r, --recursive       equivalent to --directories=recurse
      --include=FILE_PATTERN  search only files that match FILE_PATTERN
      --exclude=FILE_PATTERN  skip files and directories matching FILE_PATTERN
      --exclude-from=FILE   skip files matching any file pattern from FILE
      --exclude-dir=PATTERN  directories that match PATTERN will be skipped.
  -L, --files-without-match  print only names of FILEs containing no match
  -l, --files-with-matches  print only names of FILEs containing matches
  -c, --count               print only a count of matching lines per FILE
  -T, --initial-tab         make tabs line up (if needed)
  -Z, --null                print 0 byte after FILE name

Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM
      --color[=WHEN],
      --colour[=WHEN]       use markers to highlight the matching strings;
                            WHEN is `always', `never', or `auto'
  -U, --binary              do not strip CR characters at EOL (MSDOS)
  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)

沢山のオプションが用意されていることが分かりますね!

●   ●   ●

» 閉じる

さて、or検索は正規表現による検索を可能とする「-E」オプションによって、次のように実行できます。

 

$ grep -E 'w|t' tdhk.txt

iwate
akita
yamagata
tochigi
saitama
tokyo
kanagawa
niigata
toyama
ishikawa
kyoto
wakayama
tottori
tokushima
kagawa
kumamoto
oita
okinawa

 

これは “w” もしくは “t” のいずれかの文字が含まれる行を検索するコマンドです。パイプにはコマンドの実行結果を引き継ぐ機能のほか、「または」という意味をもっており、「w|t」というのは「”w” または “t”」を表しています。なお、上の例ではシングルクォーテーションで囲ってありますが、ダブルクォーテーションでも動きます。

また、or検索はパターンマッチングを調べる「-e」オプションによっても可能です。

 

$ grep -e w -e t tdhk.txt

 

これは “w” にマッチする文字列と “t” にマッチする文字列を同時に検索するコマンドです。多くのウェブサイトでは主にこちらの方法が紹介されているようです。

実は、オプションを使わずパイプ文字をエスケープすることでor検索することができます。

 

$ grep 'w\|t' tdhk.txt

 

grep以外にもパターンマッチングを調べるコマンドとして、awkやsedなどがあります。

 

 その他の便利なオプション

上記以外によく使われるオプションをご紹介します。

「-v」オプション

:特定の文字列を含まない行を表示

$ grep -v a tdhk.txt

tochigi
tokyo
fukui
gifu
mie
kyoto
hyogo
tottori
ehime
kochi

「-c」オプション

:特定の文字列を含む行数を表示

$ grep -c a tdhk.txt

37

「-A」オプション

:特定の文字列を含む行から下に指定行だけ表示

$ grep -A 5 tokyo tdhk.txt

tokyo
kanagawa
niigata
toyama
ishikawa
fukui

「-B」オプション

:特定の文字列を含む行から上に指定行だけ表示

$ grep -B 5 tokyo tdhk.txt

ibaraki
tochigi
gunma
saitama
chiba
tokyo

「-C」オプション

:特定の文字列を含む行の前後を指定行だけ表示

$ grep -C 5 tokyo tdhk.txt

ibaraki
tochigi
gunma
saitama
chiba
tokyo
kanagawa
niigata
toyama
ishikawa
fukui

「-n」オプション

:特定の文字列を含む行と行番号を表示(ファイル処理の際に便利です)

$ grep -n kyo tdhk.txt

13:tokyo
26:kyoto

 

その他にも色々なオプションがあります。

「-i」オプション

:大文字と小文字を区別せず検索する

「-h」オプション

:検索結果にファイル名を表示しない(ファイルの多いディレクトリ内で使うことが多い)

「-H」オプション

:検索結果と一緒にファイル名を表示する(「-H」オプションの逆)

「-l」オプション

:該当する文字列を含むファイル名のみ表示する(ファイルの多いディレクトリ内で使うことが多い)

「-L」オプション

:該当する文字列を含まないファイル名のみ表示する(「-l」オプションの逆)

「-o」オプション

:特定の文字列に一致した文字だけを表示する(単体ではあまり使わないイメージがあります)

「-r」オプション

:ディレクトリ内も検索対象とする

●   ●   ●

取り敢えずはこのくらいで十分でしょうか?この他にも紹介していないオプションがありますので、必要に応じてusageを確認してください。


今回はgrepコマンドの基本的な使い方についてまとめました。シェルスクリプトを書く際にもよく使われますし、ファイル内検索やディレクトリの検索で頻繁に使用するコマンドなので是非慣れておきたいですね!

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です