助け合いフォーラム
$ cat test.txt
b!
ba!
bu!
buu!
buuu!
正解
b!
bu!
解説
grepコマンドはファイルや標準入力から、正規表現のパターンにマッチする文字列を含む行を抽出します。
grepコマンドの書式は以下のとおりです。
grep [オプション] 検索パターン [ファイル名]
以下は主な正規表現とその使用例をまとめたものです。
上表より、「bu?!」は、文字「b」の後に「u」を0回もしくは1回繰り返して、その後に文字「!」がくる文字列を意味します。
このパターンの文字列を含む行は「b!」「bu!」の2行です。
したがって正解は
・b!
・bu!
です。
なお「?」は拡張正規表現ですので、grepコマンドの「-E」オプションを使用するか、egrepコマンドを使用する必要があります。
以下は実行例です。
その他の選択肢は「grep -E 'bu?!' test.txt」を実行した際に表示されませんので、誤りです。
参考
正規表現とは、文字列の特定のパターンを認識する為に使用する表現方法です。文字列の検索や置換などを行う際に利用します。正規表現には基本正規表現(BRE: Basic Regular Expression)と拡張正規表現(ERE: Extended Regular Expression)があります。
以下は主な正規表現とその使用例をまとめたものです。
なお、正規表現の「*」と、シェルによって解釈されるメタキャラクタの「*」では意味が異なるので注意してください。シェルは「*」を0文字以上の文字列と解釈します。
正規表現は明示的に「'」(シングルクォーテーション)や「"」(ダブルクォーテーション)の引用符で囲う事ができます。これらの引用符で囲まれた正規表現の記号は、シェルにメタキャラクタとして扱われなくなります。
正規表現を利用する主なコマンドは以下のとおりです。
・grep
ファイルや標準入力から、検索パターンにマッチする文字列を含む行を抽出するコマンド
なお、「-E」オプションを併用すると拡張正規表現が使えます(egrepコマンドと同様)。
・sed
ファイルや標準入力の内容を編集して表示するコマンド
例1)1から5までのいずれかの文字がある行を「test.txt」ファイルから抽出する場合
$ grep '[1-5]' test.txt
例2)「test.txt」ファイルの「#」から始まる行を削除して出力する場合
$ sed '/^#/d' test.txt
基本正規表現と拡張正規表現の違いに注意してください。grepコマンドは、-Eオプションを付けないと検索パターンを基本正規表現と判断しますので、上表の拡張正規表現が使えません。
実行例)
基本正規表現では「?, +」は「\?, \+」とすることで、拡張正規表現と同様の意味を持つようになります。
シングルクォートについて
シングルクォートで囲むと全てが文字列扱いだと思うのですが、なぜ問題では拡張正規表現として扱われるのでしょうか。ご教授頂けると嬉しいです。
「grep -E 'bu?!' test.txt」
のことですかね?
「bu?!
」は「拡張正規表現」を使って記載された文字列なので、grepは「拡張正規表現」として理解している、と言うだけですよ。
ちなみに、
シングルクォートで囲むと全てが文字列扱い
と言うのは、grepにとってではなく「シェル(多くはbash)」にとってなので、「誰がどう扱うことでどう見えるのか」をきっちり理解しておくのが良いと思います。
コメント
この投稿に対して返信しませんか?
s satuki1127
2022/09/25 22:53
arashi1977様 ご回答ありがとうございます。 コマンド中のシングルクォートもエスケープ的な意味を持っているのかと思っとおりました。 納得して次に進めます。 ありがとうございました。