レンジ
正規表現の範囲の表現方法を学ぶ
[A-Za-z]
任意の文字
[0-9]
任意の数字
[a-z_]
小文字の英字もしくは、アンダースコア
[349]
3, 4, もしくは 9 にマッチする
サンプル
シェルの中で定義されている関数の一覧を取得する。declare -f
そして、grep で先頭が小文字もしくはアンダースコアのものを抽出する。
$ declare -f | grep '^[a-z_]'
__expand_tilde_by_ref ()
__get_cword_at_cursor_by_ref ()
__git_eread ()
:
_xfunc ()
_xinetd_services ()
command_not_found_handle ()
dequote ()
quote ()
quote_readline ()
logroate.d
が4もしくは6で終わる行を検索する。$
は行末の意味
grep 'rotate [46]$' /etc/logrotate.d/*
/etc/logrotate.d/rsyslog: rotate 4
/etc/logrotate.d/ufw: rotate 4
/etc/logrotate.d/unattended-upgrades: rotate 6
/etc/logrotate.d/waagent.logrotate: rotate 6
ちなみに、レンジの中で^
を使うとnegateつまり反対の意味になるようだ。この例だとrotate ...
で終わりが4以外
/etc/logrotate.d/apport: rotate 7
/etc/logrotate.d/lxd: rotate 7
/etc/logrotate.d/rsyslog: rotate 7
/etc/logrotate.d/unattended-upgrades: rotate 6
/etc/logrotate.d/waagent.logrotate: rotate 6
Serverだけど、先頭が大文字でも小文字でもヒットさせる
$ grep '[Ss]erver' /etc/ntp.conf
# Specify one or more NTP servers.
# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# Use Ubuntu's ntp server as a fallback.
# Note that "restrict" applies to both servers and clients, so a configuration
# up blocking replies from your own upstream servers.
# Local users may interrogate the ntp server more closely.
# server 127.127.8.1 mode 135 prefer # Meinberg GPS167 with PPS
# server 127.127.22.1 # ATOM(PPS)
文字のバウンダリ
\s
ホワイトスペース
\ssystem
は、例えばfile system
にマッチする
\b
文字の境界線。明確な仕様は、システムによって違うらしいが、例えば、空白とかハイフンとか。試してみると結構ヒットする。
$ cat ./words
word
word
-word-
(word)
{word}
[word]
$ grep '\bword\b' ./words
word
word
-word-
(word)
{word}
[word]
実際にやってみる。区切り文字のあるものにヒット
$ grep 'server\b' /etc/ntp.conf
# Use Ubuntu's ntp server as a fallback.
# Local users may interrogate the ntp server more closely.
# server 127.127.8.1 mode 135 prefer # Meinberg GPS167 with PPS
# server 127.127.22.1 # ATOM(PPS)
\s
で空白に限定してヒット
$ grep 'server\s' /etc/ntp.conf
# Use Ubuntu's ntp server as a fallback.
# Local users may interrogate the ntp server more closely.
# server 127.127.8.1 mode 135 prefer # Meinberg GPS167 with PPS
# server 127.127.22.1 # ATOM(PPS)
\S
で複数形にヒット。ちなみに、\S
は非空白文字。
$ grep 'server\S' /etc/ntp.conf
# Specify one or more NTP servers.
# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# Note that "restrict" applies to both servers and clients, so a configuration
# up blocking replies from your own upstream servers.
pop を検索する。
$ grep pop /etc/services
pop2 109/tcp postoffice pop-2 # POP version 2
pop2 109/udp pop-2
pop3 110/tcp pop-3 # POP version 3
pop3 110/udp pop-3
pop3s 995/tcp # POP-3 over SSL
pop3s 995/udp
kpop 1109/tcp # Pop with Kerberos
poppassd 106/tcp # Eudora
poppassd 106/udp
pop+数字で、前後がワードの区切り
$ grep '\bpop[0-9]\b' /etc/services
pop2 109/tcp postoffice pop-2 # POP version 2
pop2 109/udp pop-2
pop3 110/tcp pop-3 # POP version 3
pop3 110/udp pop-3
ほぼ同じだけど、pop+数字の前はワード区切りの文字では無い(そんな場所は無いのtでヒットしない)
$ grep '\Bpop[0-9]\b' /etc/services
最終文字のあとが、ワード区切り文字では無い
$ grep 'pop[0-9]\B' /etc/services
pop3s 995/tcp # POP-3 over SSL
pop3s 995/udp
Quantifiers
'*'
u*
は、uが0以上出現する事にマッチ
'?'
`u?' は、uが0もしくは、1回のみ出現にマッチ
'+'
'u+' は、uが1以上出現する事にマッチ
'{n}`
'u{3}は
uuu` にマッチする
サンプル
とても良いサンプルだったので、そのまま。
test
#start
start end
start end
startend
b
#bb
bbb
# end
これを元に正規表現をテストします。
start のマッチ
$ grep 'start' ./test
#start
start end
start end
startend
'start end' のマッチ
$ grep 'start end' ./test
start end
'start' と 'end' の間に0以上複数のスペースとマッチ
grep 'start\s*end' test
start end
start end
startend
'start' と 'end' の間に一つの空白とマッチ
のはずが出ない。
$ grep 'start\s?end' test
$
これは、grep が標準で拡張の構文に対応していないため。-E
オプションをつけると対応される。これで1文字もしくは、0文字の空白のマッチが確認できる。
$ grep -E 'start\s?end' test
start end
startend
具体的な繰り返し回数のマッチも次の通り。
$ grep -E 'start\s{2}end' test
start end
ファイルを改造して、追加する。
test
#start
start end
start end
startend
b
#bb
bbb
# end
ab12 7af
a234 7ef
もう少し複雑なパターンを試してみる。英字二文字、そのあと、数字が一文字、もしくは二文字というパターンマッチ
$ grep -E '[a-z]{2}[0-9]{1,2}' test
ab12 7af
うん。正規表現をは強力やな。
サンプル
ソーシャルセキュリティナンバーを検索する
employee
Tsuyoshi,Ushio, 232-78-3456
Michael,Jackson,,
Foo,Bar,xxx-xx-xxxx
Hello,World,1879-0
Elton,Jhon,345-23-2313
Muddy,Waters,563-23-8137
Steve,Vai,,
最初に、grep -vE
を指定して検索。-v
はマッチを反転するので、ヒットしないものが対象になる。ソーシャルセキュリティナンバーは、999-99-9999
的なフォーマットなので次のようになる。
$ grep -vE '\b[0-9]{3}-[0-9]{2}-[0-9]{4}\b' employees
Michael,Jackson,,
Foo,Bar,xxx-xx-xxxx
Hello,World,1879-0
Steve,Vai,,
ちゃんとマッチさせるには、-v
をとる
$ grep -E '\b[0-9]{3}-[0-9]{2}-[0-9]{4}\b' employees
Tsuyoshi,Ushio, 232-78-3456
Elton,Jhon,345-23-2313
Muddy,Waters,563-23-8137
ついでだからドライバーズライセンスもやってみよう。New numbers will begin with “WDL” followed by a string of nine randomly assigned letters or numbers.なので簡単そう。
$ cat drivers
Tsuoyshi,Ushio, WDL23N6BG23B
Yamada,Taro, XXXXXXXXXXXX
Sanda,Yu,,
Takeru,Ushio, WDL15NB6G22C
うん。簡単だった。
$ grep -E '\bWDL[0-9,A-Z]{9}\b' drivers
Tsuoyshi,Ushio, WDL23N6BG23B
Takeru,Ushio, WDL15NB6G22C