4

基本的な*,?および[...]パターンに加えて、Bash シェルは、!(pattern-list)(「指定されたパターンの 1 つを除くすべてに一致する」) のような拡張パターン マッチング演算子を提供します。それらを使用するには、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

サブシェルで実行するプログラムにシェル式を渡すと、演算子によってエラーが発生します。サブシェルを直接実行するテストを次に示します (ここでは、展開が時期尚早に発生しないことを確認するために、別のディレクトリから実行しています)。

~/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)'

どんな解決策でも大歓迎です!

4

4 に答える 4

4

bash は実行前に各行を解析するため、bash がグロビング パターン構文を検証している場合、「shopt -s extglob」は有効になりません。このオプションは、同じ行で有効にすることはできません。そのため、(Randy Proctor による) "bash -O extglob -c 'xyz'" ソリューションが機能し、必要とされます。

于 2010-08-12T03:56:03.387 に答える
3
$ bash -O extglob -c 'echo !(file2)'
ファイル1 ファイル3
于 2009-02-09T17:40:46.560 に答える
3

回避したい場合、およびサブシェル内でextglobのオンとオフevalを切り替える必要がある場合は、別の方法があります。パターンを変数に入れるだけです:

bash -c 'shopt -s extglob; cd test; patt="!(file2)"; echo $patt; shopt -u extglob; echo $patt'

次の出力が得られます。

file1 file3
!(file2)

extglobが設定および設定解除されたことを示します。最初のechoが を引用符で囲んでいた場合$patt、2 番目のパターンのようにパターンを吐き出すだけですecho(おそらく引用符が必要です)。

于 2009-06-05T04:47:11.420 に答える
1

まあ、私はextglobの実際の経験はありませんが、echoでラップすることで動作させることができますeval:

$ bash -c 'shopt -s extglob ; cd  test ; eval "echo !(file2)"'
file1 file3
于 2009-02-09T17:34:03.597 に答える