引用された式で拡張されたパス名展開パターンをエスケープするには?
-
22-08-2019 - |
質問
基本*
、?
と[...]
パターンに加えて、バッシュシェルは(「所定のパターンの一つを除いてすべてに一致」)!(pattern-list)
ような演算子をマッチング延在パターンを提供します。 extglob
シェル・オプションは、それらを使用するように設定する必要があります。例:
~$ mkdir test ; cd test ; touch file1 file2 file3
~/test$ echo *
file1 file2 file3
~/test$ shopt -s extglob # make sure extglob is set
~/test$ echo !(file2)
file1 file3
Iサブシェルでそれを実行するプログラムにシェル表現を渡した場合、は、オペレータがエラーを引き起こします。ここでは(ここで私は拡張が早まっ起こらないことを確認するために、別のディレクトリから実行しています)直接サブシェルを実行し、テストがあります:
~/test$ cd ..
~$ bash -c "cd test ; echo *"
file1 file2 file3
~$ bash -c "cd test ; echo !(file2)" # expected output: file1 file3
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'
私はエスケープのすべての種類を試してみたが、私は作ってみた何が正しく働いていません。私も疑わextglob
をサブシェルで設定されていないが、それはケースではありませんされます:
~$ bash -c "shopt -s extglob ; cd test ; echo !(file2)"
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'
すべてのソリューションが高く評価!
解決
$ bash -O extglob -c 'echo !(file2)' file1 file3
他のヒント
bashはそれを実行する前に、それぞれの行を解析し、そのbashはグロブパターン構文を検証しているとき、「shopt -s extglobは、」影響を取っていません。オプションでは、同じ行に有効にすることはできません。 (ランディ・プロクターから)「bashの-O extglob -c 『XYZ』」ソリューションが動作し、必要とされる理由です。
eval
を避けたいとあなたがのextglob の上とサブシェル内でオフにすることができる必要がある場合は、ここでは、別の方法です。ただ、変数に自分のパターンを入れます:
bash -c 'shopt -s extglob; cd test; patt="!(file2)"; echo $patt; shopt -u extglob; echo $patt'
この出力を与えます:
file1 file3
!(file2)
のextglob の設定と解除されたことを示しています。最初echo
が$patt
の前後に引用符を持っていた場合、それだけで(おそらく引用符を持つべきである)は、第2のecho
のようなパターンを吐き出すだろう。
まあ、私はのextglob の持つ任意の実際のexperinceを持っていないが、私はそれがecho
でeval
をラップすることによって動作するように取得することができます:
$ bash -c 'shopt -s extglob ; cd test ; eval "echo !(file2)"'
file1 file3