
- はじめに
- 検索語に一致した文字列のみを抜き出して出力する
- 大文字・小文字を区別せず、検索語に一致した文字列のみを抜き出して出力する
- 検索語に一致した文字列の数をカウントする【部分一致検索】
- 検索語に一致した箇所の前後の行を出力する
- 検索語の行番号のみを出力する
- grepのエラーメッセージを消す
- まとめ
- 補足
- 参考
はじめに
「grepコマンドによる文字列処理をやってみた」の続編です。
以前扱えていなかった内容をやっていきたいです。
grepコマンドの基本については過去の記事を参照のこと。
まずは、サンプルデータをダウンロードする
svn export https://github.com/kumeS/Blog/trunk/grep_practice_02 cd ./grep_practice_02 # test.txtを使っていく。 cat test.txt #abcde #ABCDE # #abcdefghijklmnopqrstuvwxyz #ABCDEFGHIJKLMNOPQRSTUVWXYZ # #12345abcde67890fghij #12345abcde67890fghij
検索語に一致した文字列のみを抜き出して出力する
grep -oを使うと、検索後と同じものが、ヒットした文字列として出力されます。
#'abc'で検索すると、5個ヒット grep -o 'abc' test.txt #abc #abc #abc #abc #abc # -o を入れずに検索すると、'abc'を含む行数の4個でヒット grep 'abc' test.txt #abcdeabcde #abcdefghijklmnopqrstuvwxyz #12345abcde67890fghij #12345abcde67890fghij #'fghij'で検索すると、3個ヒット grep -o 'fghij' test.txt #fghij #fghij #fghij
大文字・小文字を区別せず、検索語に一致した文字列のみを抜き出して出力する
grep -o -iを使うと、大文字・小文字が区別されずに、ヒットした文字列が出力されます。
#'abc' or 'ABC'で検索され、8個ヒット grep -o -i 'abc' test.txt #abc #abc #ABC #ABC #abc #ABC #abc #abc # -i のみで検索すると、6個ヒット grep -i 'abc' test.txt #abcdeabcde #ABCDEABCDE #abcdefghijklmnopqrstuvwxyz #ABCDEFGHIJKLMNOPQRSTUVWXYZ #12345abcde67890fghij #12345abcde67890fghij #'fghij' or 'FGHIJ' で検索され、4個ヒット grep -o -i 'fghij' test.txt #fghij #FGHIJ #fghij #fghij
検索語に一致した文字列の数をカウントする【部分一致検索】
grep -oとgrep -cを使うと、検索語に一致した文字列数が出力されます。
このとき注意することとしてコマンドを分けずに、grep -o -cにすると、行数カウントになります。
#'abc'で検索して、'abc'をカウントすると、5個ヒット grep -o 'abc' test.txt | grep -c 'abc' #5 # -o -c にすると、4個ヒットで、行数カウントになる grep -o -c 'abc' test.txt #4 #'fghij'で検索すると、3個ヒット grep -o 'fghij' test.txt | grep -c 'fghij' #3
検索語に一致した箇所の前後の行を出力する
grep -Cを使うと、前後の行(行数指定)を一緒に出力できます。
#前後1行を出力する grep -C 1 'hijklmn' test.txt # #abcdefghijklmnopqrstuvwxyz #ABCDEFGHIJKLMNOPQRSTUVWXYZ #前1行、後3行を出力する grep -B 1 -A 3 'hijklmn' test.txt #123456 #abcdefghijklmnopqrstuvwxyz #ABCDEFGHIJKLMNOPQRSTUVWXYZ # #12345abcde67890fghij
grep -B -Aを使うと、-Bで検索語前の行数、-Aで検索語後の行数を指定できます。
検索語に一致した箇所の前後の文字列を出力する
上記で、行レベルで出力する方法を紹介したが、
正規表現. (ピリオド)を使うと、前後の文字列も出力できます。
#検索語を抜き出して表示 grep -o 'efghijk' test.txt #efghijk #検索語の前4文字も含めて出力 grep -o '....efghijk' test.txt #abcdefghijk #検索語の後4文字も含めて出力 grep -o 'efghijk....' test.txt #efghijklmno #検索語の前4文字、後4文字も含めて出力 grep -o '....efghijk....' test.txt #abcdefghijklmno
また、検索語を「変数」で指定することもできる。
TERMS=$"efghijk" ; grep -o "....$TERMS...." test.txt #OR TERMS=$'efghijk' ; grep -o "....$TERMS...." test.txt #abcdefghijklmno
やってみると、'と"の組み合わせが重要らしいです。
;は、複数文を繋げて書く文法である。
検索語を行番号付きで出力する
grep -nを使うと、行番号付きで出力されます。
#'abc'行を行番号付きで出力 grep -o -n 'abc' test.txt #1:abc #abc #4:abc #7:abc #8:abc grep -n 'abc' test.txt #1:abcdeabcde #4:abcdefghijklmnopqrstuvwxyz #7:12345abcde67890fghij #8:12345abcde67890fghij #'fghij'行を行番号付きで出力 grep -o -n 'fghij' test.txt #4:fghij #7:fghij #8:fghij
検索語の行番号のみを出力する
行番号のみを出力するには、sedとの組み合わせで行います。
#'abc'行を行番号のみ出力 grep -n 'abc' test.txt | sed -e 's/:.*//g' #1 #4 #7 #8 #'fghij'行を行番号のみ出力 grep -n 'fghij' test.txt | sed -e 's/:.*//g' #4 #7 #8
grepのエラーメッセージを消す
そのままではあまり使わないけど、プログラムを組むときには役に立つかもです。
#フォルダに実行するとエラーが出る grep 'abcd' test grep: test: Is a directory grep -s 'abcd' test #OR grep --no-messages 'abcd' test #エラーメッセージの非表示
まとめ
grepコマンドは結構役に立つので、一通り覚えておくと、
いろいろなテキストの前処理とかに使えそうです。
補足
正規表現のまとめ
正規表現 (Regular Expression)は、文字列のパターン・マッチングなどの表記法として使用する。
また、メタキャラクタとは、文字列のパターンを表す特殊な記号のことを指す。
| メタキャラクタ | そのメタキャラクタが意味すること |
|---|---|
| . | 任意の一文字 |
| * | 前にある文字の0回以上の繰り返し |
| + | 前にある文字の1回以上の繰り返し |
| ? | 前にある文字の0回あるいは1回の意味 |
| ^ | 指定した文字が文頭 |
| $ | 指定した文字が文末 |
| [ ] | 指定した複数の文字の中のいずれか |
| { } | 前にある文字の指定した回数の繰り返し |
| \w | 英数文字またはアンダーバー。[a-zA-Z0-9_]と同等 |
| \W | \w 以外の文字 |
| \d | 数値文字。[0-9]と同等 |
| \D | 数値以外の文字。[^0-9]と同等 |
| \s | 空白文字 |
| \S | 空白以外の文字 |
| \b | ワードの先頭、あるいは末尾にマッチ |
| \B | ワード内の文字列にマッチ |
| \A | 文字列の最初にマッチ |
| \Z | 文字列の最後にマッチ |
| \t | タブ |
| \n | 改行 |
| \r | キャリッジリターン |