はじめに
種田梨沙さん、お誕生日おめでとうございます。
Act-4を思い出して、うう。。😭1 nikkieです。
grep
や正規表現まわりで最近の学びです
目次
grep -o
大変お世話になっているgrep
。
『マスタリングLinuxシェルスクリプト 第2版』より(8.1)
grep(global regular expression print)、すなわち私たちが一般的にgrepコマンドと呼んでいるものはコマンドラインツールの1つであり、検索をグローバルに(つまり、ファイル内のすべての行について)行い、その結果を標準出力STDOUTに出力します。
検索文字列として正規表現を使います。
検索文字列に一致する部分のある行を出力できます
今回-o
を知りました。
これは--only-matching
の略。
一致した部分だけを取り出します2。
% cat example.txt boto3 1.26.59 botocore 1.29.59 % grep boto example.txt boto3 1.26.59 botocore 1.29.59 % grep -o boto example.txt # 一致する部分のみ! boto boto
肯定先読み
検索文字列に「肯定先読み」なるものが使えることを知りました。
grep -P
と一緒に使います。
なおmacOSのデフォルトのgrep
は-P
をサポートしていませんでした。
GNU grepをbrew install grep
してggrep
を使います。
『正規表現辞典 改訂新版』(03-07-02)を参考にした例
% cat files.txt
sample1.doc
example2.txt
sample3.log
(?=pattern)
はpatternが右(=先)に存在する場合にマッチします。
grep -P
は--perl-regexp
(検索文字列をPerl互換正規表現として扱う)
% ggrep -P '.*(?=\.doc|\.txt|\.log)' files.txt sample1.doc example2.txt sample3.log
grep -o
と組み合わせると、拡張子を除いて取り出せます!3
% ggrep -oP '.*(?=\.doc|\.txt|\.log)' files.txt sample1 example2 sample3
肯定戻り読み
肯定先読み(右を見る)とは逆に、左を見るのが「肯定戻り読み」。
『正規表現辞典 改訂新版』では03-07-04です。
これらを知るきっかけとなったのが以下のようなファイル。
ログファイルのうち識別子(ここでは拡張子を除いたファイル名)を取り出したいというシーンです。
% cat practical.txt file= sample1.doc file= example2.txt file= sample3.log
肯定先読みだけだと
% ggrep -oP '.*(?=\.doc|\.txt|\.log)' practical.txt file= sample1 file= example2 file= sample3
左側が残ります(.*
は左側にもマッチしているため)。
ここに肯定戻り読み(?<=pattern)
も合わせると
% ggrep -oP '(?<=file= ).*(?=\.doc|\.txt|\.log)' practical.txt sample1 example2 sample3
拡張子を除いたファイル名が取り出せました!
終わりに
学びのまとめです
grep
は-o
でマッチする部分だけを取り出せるgrep -P
で、肯定先読み(?=pattern)
・肯定戻り読み(?<=pattern)
が使える- これらを使って、テキスト中からほしい部分を取り出した(ログ中のファイル名を例に)
いずれも知らなかったのですが、GitHub Copilotに入力と期待出力を与えて、コマンドを生成させる中で知りました。
Copilotと戯れるイメージ
# 入力 file= sample1.doc file= example2.txt file= sample3.log # 期待出力 sample1 example2 sample3 # コマンド