Bash
パターンマッチングと正規表現
サーチ…
構文
- $ shopt -u option#Bashの組み込みオプションを無効にする
- $ shopt -s option#Bashの組み込みオプションを有効にする
備考
文字クラス
[] globの有効な文字クラスは、POSIX標準で定義されています。
アルナムアルファベット空白cntrl数字グラフ下の印刷区画スペース上の単語xdigit
[]内に複数の文字クラスまたは範囲を使用することができます(例:
$ echo a[a-z[:blank:]0-9]*
aで始まり、小文字または空白または数字のあとに続くファイルに一致します。
こと、しかし、心に留めておくべきである[]グロブのみを完全に否定し、それのない部分だけすることができます。否定文字は 、開始に続く最初の文字でなければなりません [例えば、この式は、 a始まらないすべてのファイルと一致します
$ echo [^a]*
以下は、数字または^で始まるすべてのファイルに一致します。
$ echo [[:alpha:]^a]*
^がリテラル^として解釈されるため、 a以外の文字で始まるファイルやフォルダとは一致しません 。
グロブ文字をエスケープする
ファイルまたはフォルダには、名前の一部としてグロブ文字が含まれている可能性があります。この場合、globはリテラルマッチのために先行する\でエスケープすることができます。別のアプローチは、ファイルのアドレス指定にダブル""またはシングル''引用符を使用することです。 Bashは""または''囲まれたグロブを処理しません。
正規表現との違い
グロブと正規表現の最も大きな違いは、有効な正規表現には修飾子と量指定子が必要であることです。修飾子は一致するものを識別し、量子は修飾子に一致する頻度を示します。同等の正規表現*グロブがある.*場所.任意の文字を表し、 *は前の文字の0以上の一致を表します。 ?の同等の正規表現? globは.{1}です。これまでのように、修飾子.任意の文字に一致し、 {1}は直前の修飾子と一度だけ一致することを示します。これは、と混同してはいけません? RegExで1回または1回一致します。 [] globは、RegExで同じように使用することができます。ただし、必須の数量子が続く場合に限ります。
等価正規表現
| グローブ | 正規表現 |
|---|---|
* | .* |
? | . |
[] | [] |
文字列が正規表現と一致するかどうかを確認する
文字列が正確に8桁で構成されているかどうかを確認します。
$ date=20150624
$ [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" || echo "no"
yes
$ date=hello
$ [[ $date =~ ^[0-9]{8}$ ]] && echo "yes" || echo "no"
no
* glob
準備
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
アスタリスク*は、おそらく最も一般的に使用されるグロブです。これは単に任意の文字列にマッチします
$ echo *acy
macy stacy tracy
単一の*はサブフォルダにあるファイルとフォルダと一致しません
$ echo *
emptyfolder folder macy stacy tracy
$ echo folder/*
folder/anotherfolder folder/subfolder
** glob
準備
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -s globstar
Bashは2つの隣接するアスタリスクを1つのグロブとして解釈できます。 globstarオプションを有効にすると、これを使用して、ディレクトリ構造のより深いところにあるフォルダを照合することができます
echo **
emptyfolder folder folder/anotherfolder folder/anotherfolder/content folder/anotherfolder/content/deepfolder folder/anotherfolder/content/deepfolder/file folder/subfolder folder/subfolder/content folder/subfolder/content/deepfolder folder/subfolder/content/deepfolder/file macy stacy tracy
**はパスがどれほど深いものであっても、パスの拡張と考えることができます。この例では、ネストされているdeepにかかわらず、 deepで始まるファイルまたはフォルダに一致します。
$ echo **/deep*
folder/anotherfolder/content/deepfolder folder/subfolder/content/deepfolder
?グロブ
準備
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
?単に正確に1文字にマッチする
$ echo ?acy
macy
$ echo ??acy
stacy tracy
[]グロブ
準備
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
特定の文字と一致する必要がある場合、 '[]'を使用できます。 '[]'の中にある文字は、一度だけ一致します。
$ echo [m]acy
macy
$ echo [st][tr]acy
stacy tracy
しかし、 []グロブはそれだけではありません。また、ネガティブマッチや、文字や文字クラスの範囲のマッチングも可能です。負のマッチは!または^以下の最初の文字として[ 。私たちはstacyと
$ echo [!t][^r]acy
stacy
ここでは、bashにt始まらないファイルと、2番目の文字がrでなく、ファイルがacy終わるファイルのみをacyするようにacyます。
文字のペアをハイフン( - )で区切ることで、範囲を一致させることができます。 2つの囲み文字(両端を含む)の間にある文字はすべて一致します。例えば、 [rt]は[rst]と等価です[rst]
$ echo [r-t][r-t]acy
stacy tracy
文字クラスは[:class:]でマッチさせることができます。例えば、空白を含むファイルをマッチさせるためです
$ echo *[[:blank:]]*
file with space
マッチする隠しファイル
準備
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Bashビルトインオプションのdotglobでは、隠しファイルとフォルダ、つまりaで始まるファイルとフォルダを一致させることができます.
$ shopt -s dotglob
$ echo *
file with space folder .hiddenfile macy stacy tracy
大文字と小文字の区別なし
準備
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
nocaseglobオプションを設定すると大文字小文字を区別しないでglobとマッチする
$ echo M*
M*
$ shopt -s nocaseglob
$ echo M*
macy
グロブが何にもマッチしないときの動作
準備
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
グロブが何もマッチしない場合、結果はオプションnullglobとfailglobによって決まります。どちらも設定されていなければ、Bashは一致するものがなければglob自体を返します
$ echo no*match
no*match
nullglobがアクティブ化されている場合は、何も返されません( null )。
$ shopt -s nullglob
$ echo no*match
$
failglobがアクティブになっていると、エラーメッセージが返されます。
$ shopt -s failglob
$ echo no*match
bash: no match: no*match
$
ことに注意してください、 failglobオプションが優先さnullglob場合、すなわち、オプションをnullglobとfailglob不一致の場合には- -エラーが返され、その後、両方が設定されています。
拡張グロビング
準備
$ mkdir globbing
$ cd globbing
$ mkdir -p folder/{sub,another}folder/content/deepfolder/
touch macy stacy tracy "file with space" folder/{sub,another}folder/content/deepfolder/file .hiddenfile
$ shopt -u nullglob
$ shopt -u failglob
$ shopt -u dotglob
$ shopt -u nocaseglob
$ shopt -u extglob
$ shopt -u globstar
Bashの組み込みextglobオプションは、globのマッチング機能を拡張することができます
shopt -s extglob
次のサブパターンは、有効な拡張グロブを構成します。
-
?(pattern-list)- 与えられたパターンの0回または1回のオカレンスに一致します。 -
*(pattern-list)- 与えられたパターンの0回以上の一致 -
+(pattern-list)- 与えられたパターンの1つ以上の出現と一致します -
@(pattern-list)- 指定されたパターンの1つに一致します。 -
!(pattern-list)- 与えられたパターンの1つを除くすべてのものにマッチする
pattern-listは、 |区切られたグロブのリストです| 。
$ echo *([r-t])acy
stacy tracy
$ echo *([r-t]|m)acy
macy stacy tracy
$ echo ?([a-z])acy
macy
pattern-list自体は、別のネストされた拡張グロブであってもよい。上記の例では、我々は我々が一致することができますことを見てきたtracyとstacyと*(rt) 。この拡張グロブそのものが否定拡張グロブ内で使用することができます!(pattern-list)と一致するために、 macy
$ echo !(*([r-t]))acy
macy
可能な限りmacyのみを残す文字r 、 s 、 t 0回以上の出現で始まらないものにマッチします。
正規表現マッチング
pat='[^0-9]+([0-9]+)'
s='I am a string with some digits 1024'
[[ $s =~ $pat ]] # $pat must be unquoted
echo "${BASH_REMATCH[0]}"
echo "${BASH_REMATCH[1]}"
出力:
I am a string with some digits 1024
1024
正規表現を変数( $pat )に代入するのではなく、次のようにすることもできます:
[[ $s =~ [^0-9]+([0-9]+) ]]
説明
-
[[ $s =~ $pat ]]構文は正規表現マッチングを実行します - キャプチャされたグループ、つまり一致結果は、 BASH_REMATCHという配列
- BASH_REMATCH配列の0番目のインデックスは、
- BASH_REMATCH配列のi番目のインデックスはi番目の捕捉されたグループです。ここでi = 1,2,3 ...
正規表現マッチから取得したグループを文字列と比較する
a='I am a simple string with digits 1234'
pat='(.*) ([0-9]+)'
[[ "$a" =~ $pat ]]
echo "${BASH_REMATCH[0]}"
echo "${BASH_REMATCH[1]}"
echo "${BASH_REMATCH[2]}"
出力:
I am a simple string with digits 1234
I am a simple string with digits
1234