$string
文字列がグローバルパターンと一致するかどうかを知りたいです$pattern
。 $string
既存のファイルの名前であってもなくてもよい。どうすればいいですか?
私の入力文字列が次の形式であるとしましょう。
string="/foo/bar"
pattern1="/foo/*"
pattern2="/foo/{bar,baz}"
$string
bashイディオムが一致するか、他の任意のグローバルパターンと一致するかどうかを確認します。これまでに試したことは次のとおりです。$pattern1
$pattern2
[[ "$string" = $pattern ]]
$pattern
グローバルパターンではなく文字列パターンとして解釈されることを除いて、ほとんど機能します。[ "$string" = $pattern ]
このアプローチの問題は、文字列が拡張された後と
$pattern
拡張の間で文字列比較が実行されることです。$string
$pattern
[[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]
この方法は機能しますが、
$string
ファイルが存在する場合にのみ可能です。[[ $string =~ $pattern ]]
=~
演算子は$pattern
グローバルまたはワイルドカードパターンではなく拡張正規表現として解釈されるため、これは機能しません。
ベストアンサー1
この問題に対する普遍的な解決策はありません。その理由は、bashで中括弧拡張(別名{pattern1,pattern2,...}
およびファイル名拡張(別名globパターン))が別々に扱われ、異なる条件と時間に拡張されるためです。以下は、bashで実行される拡張の完全なリストです。
- 支柱の拡張
- チルダ拡張
- パラメータと変数の拡張
- コマンドの置き換え
- 算術拡張
- 噴射
- パス名拡張
これらのサブセット(おそらく中括弧、チルダ、パス名の拡張)にのみ興味があるため、特定のパターンとメカニズムを使用して制御可能な方法で拡張を制限できます。たとえば、
#!/bin/bash
set -f
string=/foo/bar
for pattern in /foo/{*,foo*,bar*,**,**/*}; do
[[ $string == $pattern ]] && echo "$pattern matches $string"
done
このスクリプトを実行すると、次の出力が生成されます。
/foo/* matches /foo/bar
/foo/bar* matches /foo/bar
/foo/** matches /foo/bar
これはset -f
、パス名拡張が無効になっているため、ステートメントで中括弧拡張とチルダ拡張のみが発生するために機能しますfor pattern in /foo/{*,foo*,bar*,**,**/*}
。その後、中[[ $string == $pattern ]]
かっこ拡張を実行した後、テスト操作を使用してパス名拡張をテストできます。