私のディレクトリには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?.txt
1つ以上のファイル名と一致するため、リスト要素はパターンと一致するファイル名のリストに置き換えられ、およびを含む2つの要素のリストがtest?.txt
生成されます。最後に、2つのパラメータとを使用して呼び出しが行われます。test1.txt
test2.txt
ls
test1
test2
を使用すると、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
。