パターンマッチングに関するオプションが存在しますが、パス名展開かそれ以外かで異なる場合があります。
例えば、シェルオプション nocaseglob
はパス名展開用で、シェルオプション nocasematch
はパス名展開以外用です。
参考「Bash Reference Manual」
参考「4.3.1 The Set Builtin - Bash Reference Manual」
参考「4.3.2 The Shopt Builtin - Bash Reference Manual」
参考「5.2 Bash Variables - Bash Reference Manual」
パターンマッチングに関しては別記事にしました。
0. まとめ
シェルオプション extglob
および globasciiranges
を除いて、名前に glob
を含むオプションはパス名展開用です。
※互換モードのバージョンによって一部の挙動が変化する場合があります。
※パス名展開用のオプションを変更してもパス名展開以外には影響しません。
※パス名展開以外用のオプションを変更してもパス名展開には影響しません。
共通:
- シェルオプション
extglob
globasciiranges
- シェル変数
LC_ALL
LC_COLLATE
LC_CTYPE
パス名展開:
- オプション
-f
-o noglob
- シェルオプション
dotglob
globskipdots
failglob
nullglob
globstar
nocaseglob
- シェル変数
GLOBIGNORE
パス名展開以外:
- シェルオプション
nocasematch
patsub_replacement
1. 共通
1.1. シェルオプション
シェルオプション | 意味 |
---|---|
extglob |
拡張パターンマッチングを有効化する |
globasciiranges |
パターン [ ...] の範囲表現を C ロケール扱いにする |
※上記のシェルオプションは正規表現には影響しません。
1.1.1. 拡張パターンマッチング
シェルオプション extglob
を有効化することで拡張パターンマッチングを利用可能になります。
シェルオプション extglob
の影響を受ける場所は以下の通りです:
- パス名展開
-
case
コマンド - パラメータ展開
- パターン削除
${parameter#pattern}
${parameter##pattern}
${parameter%pattern}
${parameter%%pattern}
- パターン置換
${parameter/pattern/string}
${parameter//pattern/string}
${parameter/#pattern/string}
${parameter/%pattern/string}
${parameter/pattern}
${parameter//pattern}
${parameter/#pattern}
${parameter/%pattern}
- 大文字小文字変換
${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,,pattern}
- パターン削除
※ 条件コマンド [[ expression ]]
では常に拡張パターンマッチングを使用可能なため、シェルオプション extglob
の影響を受けません。
shopt -s extglob
#
function f() {
echo /usr/@(lib)
case 'foo' in
@(foo)) echo 'OK' ;;
*) echo 'NG' ;;
esac
local -r parameter='foo bar'
echo "${parameter/@(foo)/baz}"
echo "${parameter#@(foo) }"
echo "${parameter^@(f)}"
}
f
/usr/lib
OK
baz bar
bar
Foo bar
1.1.2. ASCII 範囲
パターン [
...]
の範囲表現はロケールによって動作が変化しますが、シェルオプション globasciiranges
を用いることで C
ロケール扱いに出来ます。
※シェル変数の値の設定に export
は不要ですが、ここでは sort
コマンドにも設定を反映させるために export
しています。
export LC_COLLATE=en_US.UTF-8
echo -e 'A\nB\na\nb\n' | sort | xargs
shopt -s globasciiranges
echo /usr/li[A-B]
[[ 'b' == [A-B] ]] && echo 'OK' || echo 'NG'
shopt -u globasciiranges
echo /usr/li[A-B]
[[ 'b' == [A-B] ]] && echo 'OK' || echo 'NG'
a A b B
/usr/li[A-B]
NG
/usr/lib
OK
1.2. シェル変数
シェル変数 | 意味 |
---|---|
LC_ALL |
LANG および他の LC_ 変数の値を上書きする |
LC_COLLATE |
パターン [ ...] の範囲表現、等価クラス [= c=] 、照合シンボル [. symbol.] および照合順序の動作を決定する |
LC_CTYPE |
文字の解釈と文字クラス [: class:] の動作を決定する |
※コマンド実行時に直接 1 行で NAME=value command arguments
のようにシェル変数の値を変更した場合、command
の引数の arguments
に含まれるパターンに設定が反映されないため注意。
※シェル変数の値の設定に export
は不要です。
※上記のシェル変数は正規表現の一部にも影響します。
1.2.1. 照合
※シェル変数の値の設定に export
は不要ですが、ここでは sort
コマンドにも設定を反映させるために export
しています。
shopt -u globasciiranges
export LC_COLLATE=C.UTF-8
echo -e 'A\nB\na\nb\n' | sort | xargs
echo /usr/li[A-B]
[[ 'b' == [A-B] ]] && echo 'OK' || echo 'NG'
export LC_COLLATE=en_US.UTF-8
echo -e 'A\nB\na\nb\n' | sort | xargs
echo /usr/li[A-B]
[[ 'b' == [A-B] ]] && echo 'OK' || echo 'NG'
A B a b
/usr/li[A-B]
NG
a A b B
/usr/lib
OK
1.2.2. 文字タイプ
touch あ
LC_CTYPE=C.UTF-8
[[ 'あ' == [[:alpha:]] ]] && echo 'OK' || echo 'NG'
echo [[:alpha:]]
LC_CTYPE=C
[[ 'あ' == [[:alpha:]] ]] && echo 'OK' || echo 'NG'
echo [[:alpha:]]
OK
あ
NG
[[:alpha:]]
2. パス名展開
2.1. オプション
オプション | 意味 |
---|---|
-f -o noglob
|
パス名展開を無効化する |
※上記のオプションはパス名展開以外には影響しません。
※上記のオプションは正規表現には影響しません。
2.1.1. 無効化
#
set +f
echo /usr/li?
set -f
echo /usr/li?
#
set +o noglob
echo /usr/li?
set -o noglob
echo /usr/li?
/usr/lib
/usr/li?
/usr/lib
/usr/li?
2.2. シェルオプション
シェルオプション | 意味 |
---|---|
dotglob |
ファイル名 . および .. を除いて、. で始まるファイル名と暗黙的に一致するようにする |
globskipdots |
ファイル名 . および .. はパターンと一致しないようにする |
failglob |
パターンと一致しない場合はエラーにする |
nullglob |
パターンと一致しない場合は空文字列にする |
globstar |
パターン ** を有効化する |
nocaseglob |
大文字小文字を区別しない |
※後述のシェル変数 GLOBIGNORE
はシェルオプション dotglob
に影響します。
※後述のシェル変数 GLOBIGNORE
はシェルオプション globskipdots
に影響します。
※上記のシェルオプションはパス名展開以外には影響しません。
※上記のシェルオプションは正規表現には影響しません。
2.2.1. .
で始まるファイル名
ファイル名 .
および ..
を除いて、.
で始まるファイル名を扱う場合は以下のことに注意が必要です:
- シェルオプション
dotglob
が無効の場合、.
で始まるパターンと明示的に一致する-
?
や[.]
等で始まるパターンと暗黙的に一致しない
-
- シェルオプション
dotglob
が有効の場合、パターンと暗黙的に一致する-
?
や[.]
等で始まるパターンとも暗黙的に一致する
-
ファイル名 .
および ..
を扱う場合は以下のことに注意が必要です:
- シェルオプション
globskipdots
が有効の場合、パターンと常に一致しない-
.
で始まるパターンとも明示的に一致しない
-
- シェルオプション
globskipdots
が無効の場合、.
で始まるパターンと明示的に一致する- シェルオプション
dotglob
が有効でも、?
や[.]
等で始まるパターンと暗黙的に一致しない
- シェルオプション
#
shopt -u dotglob
echo ~/.ss? | basename "$(cat)"
echo ~/?ssh | basename "$(cat)"
shopt -s dotglob
echo ~/.ss? | basename "$(cat)"
echo ~/?ssh | basename "$(cat)"
#
shopt -s globskipdots
echo /.[.] | basename "$(cat)"
echo /[.]. | basename "$(cat)"
shopt -u globskipdots
echo /.[.] | basename "$(cat)"
echo /[.]. | basename "$(cat)"
.ssh
?ssh
.ssh
.ssh
.[.]
[.].
..
[.].
2.2.2. 不一致の扱い
shopt -u failglob
(echo /usr/?) 2>/dev/null || echo 'NG'
shopt -s failglob
(echo /usr/?) 2>/dev/null || echo 'NG'
/usr/?
NG
shopt -u failglob
shopt -u nullglob
echo /usr/?
shopt -s nullglob
echo /usr/?
/usr/?
2.2.3. パターン **
mkdir -p directory
touch foo directory/foo
#
shopt -u globstar
echo **/foo
shopt -s globstar
echo **/foo
directory/foo
directory/foo foo
2.2.4. 大文字小文字の区別
shopt -u nocaseglob
echo /usr/LI?
shopt -s nocaseglob
echo /usr/LI?
/usr/LI?
/usr/lib
2.3. シェル変数
シェル変数 | 意味 |
---|---|
GLOBIGNORE |
無視するファイル名の一覧 |
※コマンド実行時に直接 1 行で NAME=value command arguments
のようにシェル変数の値を変更した場合、command
の引数の arguments
に含まれるパターンに設定が反映されないため注意。
※シェル変数の値の設定に export
は不要です。
※シェル変数 GLOBIGNORE
は前述のシェルオプション dotglob
に影響します。
※シェル変数 GLOBIGNORE
は前述のシェルオプション globskipdots
に影響します。
※上記のシェル変数はパス名展開以外には影響しません。
※上記のシェル変数は正規表現には影響しません。
2.3.1. 無視するファイル名
2.3.1.1. 基本
シェル変数 GLOBIGNORE
で無視するファイル名を指定出来ます。
コロン :
区切りで複数のパターンを設定可能です。
※シェル変数 GLOBIGNORE
に相対パスを設定した場合、カレントディレクトリによって動作が異なるため注意。
※シェル変数 GLOBIGNORE
に空の値を設定した場合、設定していない扱いになります。
GLOBIGNORE=/usr/lib*
echo /usr/li?
unset GLOBIGNORE
echo /usr/li?
/usr/li?
/usr/lib
2.3.1.2. ファイル名 .
、..
および .
で始まるファイル名
ファイル名 .
、..
および .
で始まるファイル名に関しては以下のことに注意が必要です:
- ファイル名
.
および..
は必ず無視される- 前述のシェルオプション
globskipdots
が無効でも必ず無視される
- 前述のシェルオプション
- 前述のシェルオプション
dotglob
が有効になり、.
で始まるファイル名は無視されなくなる-
.
で始まるファイル名を無視したい場合はシェル変数GLOBIGNORE
にパターン.*
を追加する- ※シェル変数
GLOBIGNORE
にパターン.*
を追加した場合、.
で始まるファイル名と明示的に一致しなくなるため注意 - ※シェル変数
GLOBIGNORE
に相対パスを設定した場合、カレントディレクトリによって動作が異なるため注意
- ※シェル変数
-
shopt -u globskipdots
#
GLOBIGNORE=/usr/lib*
echo /usr/li?
echo ~/?ssh | basename "$(cat)"
echo /.[.] | basename "$(cat)"
unset GLOBIGNORE
echo /usr/li?
echo ~/?ssh | basename "$(cat)"
echo /.[.] | basename "$(cat)"
/usr/li?
.ssh
.[.]
/usr/lib
?ssh
..
2.3.1.3. シェルオプション dotglob
に対する影響
シェル変数 GLOBIGNORE
は前述のシェルオプション dotglob
に影響する場合があります:
- シェル変数
GLOBIGNORE
に空でない値が設定されると、前述のシェルオプションdotglob
が有効になる - シェル変数
GLOBIGNORE
がunset
されると、前述のシェルオプションdotglob
が無効になる - シェル変数
GLOBIGNORE
に空の値を設定しても、前述のシェルオプションdotglob
は有効にも無効にも変更されない
shopt -u dotglob
shopt dotglob || :
GLOBIGNORE=/usr/lib*
shopt dotglob || :
shopt -s dotglob
shopt dotglob || :
unset GLOBIGNORE
shopt dotglob || :
dotglob off
dotglob on
dotglob on
dotglob off
2.3.1.4. 他のオプションから受ける影響
シェル変数 GLOBIGNORE
は前述のシェルオプションの一部の影響を受けます。
シェルオプション | あり | なし |
---|---|---|
extglob |
✓ | |
globasciiranges |
✓ | |
dotglob ※ |
✓ | |
globskipdots ※ |
✓ | |
failglob |
✓ | |
nullglob |
✓ | |
globstar |
✓ | |
nocaseglob |
✓ |
※シェルオプション globstar
が有効でも、シェル変数 GLOBIGNORE
の値でパターン **
は特別な意味を持たず、パターン *
と同じ意味になるため注意。
※シェル変数 GLOBIGNORE
はシェルオプション dotglob
および globskipdots
に影響しますが、シェルオプション dotglob
および globskipdots
はシェル変数 GLOBIGNORE
に影響しません。
※シェル変数 GLOBIGNORE
に空でない値を設定後に手動でシェルオプション dotglob
を無効化した場合も、シェル変数 GLOBIGNORE
の値は .
で始まるファイル名と暗黙的に一致します。
前述の LC_
変数はシェル変数 GLOBIGNORE
に影響します。
2.3.1.5. GLOBIGNORE=.*
と shopt -u dotglob
の違い
GLOBIGNORE=.*
および shopt -u dotglob
はどちらも .
で始まるファイル名をパス名展開で無視するための設定ですが、以下のような違いがあります:
-
GLOBIGNORE=.*
-
.
で始まるファイル名はパターンと明示的に一致しない - カレントディレクトリ直下のファイルのみに影響する
-
-
shopt -u dotglob
-
.
で始まるファイル名はパターンと暗黙的に一致しない -
.
で始まるファイル名はパターンと明示的に一致する - カレントディレクトリ直下以外のファイルにも影響する
-
3. パス名展開以外
3.1. シェルオプション
シェルオプション | 意味 |
---|---|
nocasematch |
大文字小文字を区別しない |
patsub_replacement |
パターン置換 ${parameter/pattern/string} の string 内の & を有効化する |
※上記のシェルオプションはパス名展開には影響しません。
※シェルオプション nocasematch
は正規表現にも影響します。
※シェルオプション patsub_replacement
は正規表現には影響しません。
3.1.1. 大文字小文字の区別
シェルオプション nocasematch
を有効化することで大文字小文字を区別しなくなります。
シェルオプション nocasematch
の影響を受ける場所は以下の通りです:
-
case
コマンド - 条件コマンド
[[ expression ]]
- パラメータ展開
- パターン置換
${parameter/pattern/string}
${parameter//pattern/string}
${parameter/#pattern/string}
${parameter/%pattern/string}
${parameter/pattern}
${parameter//pattern}
${parameter/#pattern}
${parameter/%pattern}
- パターン置換
- プログラム補完 コマンド
-
compgen
-X filterpat
-
complete
-X filterpat
-
#
function f() {
case 'foo' in
FOO) echo 'OK' ;;
*) echo 'NG' ;;
esac
[[ 'foo' == FOO ]] && echo 'OK' || echo 'NG'
local -r parameter='foo bar'
echo "${parameter/FOO/baz}"
}
#
shopt -u nocasematch
f
shopt -s nocasematch
f
NG
NG
foo bar
OK
OK
baz bar
ちなみに、パラメータ展開のパターン削除および大文字小文字変換は影響を受けないため注意:
- パラメータ展開
- パターン削除
${parameter#pattern}
${parameter##pattern}
${parameter%pattern}
${parameter%%pattern}
- 大文字小文字変換
${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,,pattern}
- パターン削除
パターン削除で nocasematch
を使用したい場合、パターン置換や正規表現等に書き換えます。
※シェルオプション nocasematch
はパターンマッチングだけでなく正規表現にも影響します。
参考「[シェル] パターン置換 "${parameter/pattern}" を用いたパターン削除 - Qiita」
3.1.2. パターン置換の &
#
function f() {
local -r parameter='foo bar'
echo "${parameter/foo/&}"
echo "${parameter/foo/\&}"
echo "${parameter/foo/'&'}"
}
#
shopt -s patsub_replacement
f
shopt -u patsub_replacement
f
foo bar
& bar
& bar
& bar
& bar
& bar
4. 互換モード
シェル変数 BASH_COMPAT
で互換モードのバージョンを指定可能です。
※互換モードのシェルオプションは廃止予定です。
バージョン | シェルオプション |
---|---|
5.1 | (なし) |
4.2 | compat42 |
パターンマッチングに影響する互換性レベル:
- バージョン 5.1
- コマンド置換
$(command)
は解析時に拡張パターンマッチングが有効の扱いにする
- コマンド置換
- バージョン 4.2
- 二重引用符で囲まれたパターン置換
${parameter/pattern/string}
における置換文字列string
は引用符の削除を行わない
- 二重引用符で囲まれたパターン置換
参考「[Bash] 互換モード - Qiita」
参考「6.12 Shell Compatibility Mode - Bash Reference Manual」
4.1. コマンド置換 $(command)
における拡張パターンマッチング
違い:
- バージョン 5.2 以降
- 拡張パターンマッチングが無効のときにコマンド置換
$(command)
で拡張パターンを用いると、未実行であっても解析時にエラーが発生する
- 拡張パターンマッチングが無効のときにコマンド置換
- バージョン 5.1 以前
- コマンド置換
$(command)
は解析時に拡張パターンマッチングが有効の扱いにする - 拡張パターンマッチングが無効のときにコマンド置換
$(command)
で拡張パターンを用いても、それが実行されるまでに拡張パターンマッチングが有効化されればエラーは発生しない
- コマンド置換
※コマンド置換 `command`
には影響しません。
※パラメータ展開の拡張パターンには影響しません。
#
unset BASH_COMPAT
shopt -s extglob
function f() {
echo "$(echo /usr/@(lib))"
echo "$(case 'foo' in @(foo)) echo 'OK' ;; *) echo 'NG' ;; esac)"
}
shopt -s extglob
f
#
BASH_COMPAT=5.1
shopt -u extglob
function g() {
echo "$(echo /usr/@(lib))"
echo "$(case 'foo' in @(foo)) echo 'OK' ;; *) echo 'NG' ;; esac)"
}
shopt -s extglob
g
/usr/lib
OK
/usr/lib
OK
4.2. 二重引用符で囲まれたパターン置換 ${parameter/pattern/string}
における置換文字列 string
違い:
- バージョン 4.3 以降
- 引用符の削除を行う
- バージョン 4.2 以前
- 引用符の削除を行わない
#
function f() {
local -r parameter='foo bar'
echo "${parameter/foo/'baz'}"
}
#
unset BASH_COMPAT
f
BASH_COMPAT=4.2
f
#
function f() {
local -r parameter='foo bar'
echo "${parameter/foo/'baz'}"
}
#
shopt -u compat42
f
shopt -s compat42
f
baz bar
'baz' bar
二重引用符内だけでなく、ヒアドキュメント内も影響します。
#
function f() {
local -r parameter='foo bar'
cat <<-EOF
${parameter/foo/'baz'}
EOF
}
#
unset BASH_COMPAT
f
BASH_COMPAT=4.2
f
#
function f() {
local -r parameter='foo bar'
cat <<-EOF
${parameter/foo/'baz'}
EOF
}
#
shopt -u compat42
f
shopt -s compat42
f
baz bar
'baz' bar