$()のコマンドで{1,2}が印刷されないのはなぜですか?

$()のコマンドで{1,2}が印刷されないのはなぜですか?

私のディレクトリには2つのテキストファイルがあります。

$ touch test1.txt
$ touch test2.txt

Bashを使用して特定のパターンを使用してファイルを一覧表示しようとすると機能します。

$ ls test?.txt
test1.txt  test2.txt
$ ls test{1,2}.txt
test1.txt  test2.txt

ただし、次のコマンドでパターンが生成される場合$()

$ ls $(echo 'test?.txt')
test1.txt  test2.txt
$ ls $(echo 'test{1,2}.txt')
ls: cannot access test{1,2}.txt: No such file or directory

ここで何が起こっているのでしょうか?このモードが{1,2}機能しないのはなぜですか?

ベストアンサー1

それは2つの組み合わせです。まず、中括弧拡張はファイル名のパターンマッチングではありません。純粋なテキスト置換です。`a[bc]d`(括弧)と `a{b,c}d`(中括弧)の違いは何ですか?。第二に、二重引用符()以外のコマンド置換の結果を使用すると、完全なls $(…)再解析ではなくパターンマッチング(および分割: "split + glob"演算子)のみが発生します。

を使用すると、ls $(echo 'test?.txt')このコマンドはecho 'test?.txt'文字列test?.txt(末尾に改行を含む)を出力します。コマンド置換は文字列を生成しますtest?.txt(コマンド置換は末尾の改行を削除するため、最後の改行なし)。引用符のないこの置換はトークン化を行い、空白文字がないので単一の文字列リストを生成しますtest?.txt(より正確には文字はありません)。単一要素リストの各要素は条件付きワイルドカード拡張を受け、$IFS文字列にワイルドカードが含まれているため、ワイルドカード拡張が発生します。?パターンはtest?.txt1つ以上のファイル名と一致するため、リスト要素はパターンと一致するファイル名のリストに置き換えられ、およびを含む2つの要素のリストがtest?.txt生成されます。最後に、2つのパラメータとを使用して呼び出しが行われます。test1.txttest2.txtlstest1test2

を使用すると、ls $(echo 'test{1,2}')このコマンドはecho 'test{1,2}'文字列test{1,2}(末尾に改行を含む)を出力します。コマンド置換の結果は文字列ですtest{1,2}。引用符のないこの置換はトークン化を実行して個々の文字列のリストを生成しますtest{1,2}。単一要素リストの各要素は条件付きワイルドカード拡張を受けますが、文字列にワイルドカードがないため、何もしません(要素はそのままです)。ls単一の引数で呼び出されますtest{1,2}

比較のために、次のことが起こりますls $(echo test{1,2})。このコマンドはecho test{1,2}文字列test1 test2(末尾に改行を含む)を出力します。コマンド置換の結果は文字列ですtest1 test2(最後の改行文字はありません)。引用符のないこの置換は単語分割を実行して2つの文字列のtest1合計を生成しますtest2。その後、両方の文字列にワイルドカードが含まれていないため、単独で残すため、両方のls引数test1とを使用して呼び出しが行われますtest2

おすすめ記事