回答:
なぜなら、それらは2つの異なるものだからです。{1,2,3}
一例であるブレース拡張。{1,2,3}
コンストラクトは拡張され、シェルによって前に、echo
でもそれを見ています。あなたが使用すると何が起こるかを見ることができますset -x
:
$ set -x
$ echo {1,2,3}
+ echo 1 2 3
1 2 3
ご覧のとおり、コマンドecho {1,2,3}
は次のように展開されています。
echo 1 2 3
ただし、[[:digit:]]
はPOSIX文字クラスです。に渡すとecho
、シェルも最初に処理しますが、今回はシェルグロブとして処理されます。echo *
現在のディレクトリ内のすべてのファイルを印刷する場合と同じように動作します。しかし[[:digit:]]
、どの数字にも一致するシェルグロブです。bashでは、シェルグロブが何にも一致しない場合、それ自体に展開されます。
$ echo /this*matches*no*files
+ echo '/this*matches*no*files'
/this*matches*no*files
グロブが何かと一致する場合、それが出力されます:
$ echo /e*c
+ echo /etc
/etc
どちらの場合echo
も、シェルが印刷するように指示したものをすべて印刷しますが、2番目の場合は、グロブが何か(/etc
)と一致するため、その何かを印刷するように指示されます。
したがって、名前が正確に1桁([[:digit:]]
一致するもの)で構成されるファイルまたはディレクトリがないため、グロブはそれ自体に展開され、次のようになります。
$ echo [[:digit:]]
[[:digit:]]
次に、というファイルを作成し5
て、同じコマンドを実行してみます。
$ echo [[:digit:]]
5
そして、複数の一致するファイルがある場合:
$ touch 1 5
$ echo [[:digit:]]
1 5
これは(このような)この動作をオフman bash
にするnullglob
オプションの説明に記載されています。
nullglob
If set, bash allows patterns which match no files (see
Pathname Expansion above) to expand to a null string,
rather than themselves.
このオプションを設定した場合:
$ rm 1 5
$ shopt -s nullglob
$ echo [[:digit:]] ## prints nothing
$
shopt -s failglob
ような最新のシェルの動作と同様の、より有用な動作を得るためにも参照してください。zsh
fish
failglob
。nullglob
予期しない問題が発生する可能性があります。たとえば、たまたまが含まれているURLを貼り付ける場合など?
です。
nullglob
はパターンがシェルによってグロブとして解釈されていることを示すためだけに言及しました。
{1,2,3}
あるブレース展開は、それはその意味を考慮せずにリストされた単語に展開されます。
[...]
アスタリスクや疑問符と同様に、ファイル名の展開(またはワイルドカード、グロブ)で使用される文字グループです。これは、リストされている場合のように、名前付きグループのメンバーである文字、またはそれらにリストされている場合に一致します。ほとんどのシェルのデフォルトの動作では、一致するファイルがない場合、ワイルドカードをそのままにします。*
?
[:digit:]
(ワイルドカード/パターンをそれが一致する文字列のセットに実際に変換することはできないことに注意してください。アスタリスクは任意の長さの任意の文字列と一致できるため、それを含むパターンを展開すると文字列の無限リストが生成されます。)
そう:
$ bash -c 'echo [[:digit:]]' # bash leaves it as-is
[[:digit:]]
$ zsh -c 'echo [[:digit:]]' # zsh by default complains if no match
zsh:1: no matches found: [[:digit:]]
$ touch 1 3 d i g t
$ bash -c 'echo [[:digit:]]' # now there are two matches
1 3 # note that d, i, g and t do NOT match
それでも:
$ bash -c 'echo {1,2,3}'
1 2 3
それらの両方は、シェルによって展開され、それはあなたがしているが、実行中のコマンドがある場合は問題ではないls
、またはecho
かrm
。また、これらのいずれかが引用されている場合、展開されないことに注意してください。
$ bash -c 'echo "[[:digit:]]"' # even though matching files still exist
[[:digit:]]
$ bash -c 'echo "{1,2,3}"'
{1,2,3}
[[:digit:]]
前にそれを渡していないecho
ので、echo
決して見て[[:digit:]]
、それだけで見ています1 3
。あなたは実行することにより、この動作を確認することができますset -x
(実行、実行されている実際のコマンドを出力しますどのset +x
再びそれをオフにします)。
echo
ファイルを検索しません。echo
{1,2,3}
(たとえば{1..3}
、中かっこ展開です。これらは、コマンド実行前にシェルによって解釈されます。
[[:digit:]]
はパターンマッチングトークンですが、そのパターンに一致するファイルがある場所では使用していません。一致しないパターンマッチを使用すると、それ自体に展開されます。
$ echo [[:digit:]]; touch 3; echo [[:digit:]]
[[:digit:]]
3