bashスクリプトでrm -v!(* .yaml)を実行するには?

bashスクリプトでrm -v!(* .yaml)を実行するには?

スクリプトは次のとおりです。

rm -v !\(*.yaml\) ;\

これは生産します

rm: cannot remove '!(*.yaml)': No such file or directory

しかし、コマンドラインではうまく機能します。脱出のためにさまざまな方法を試しました。

'\!\(\*.yaml\)'
`\!\(\*.yaml\)`
`!\(*.yaml\"\)`
"\!\(\*.yaml\)"

適切なエスケープシーケンスを見つけることができないようです。理解できません。括弧を削除することが私の最初のステップでした。そして脱出を試みたし!、その後は*。また、バックティックエスケープ解除を試してみましたが、「rm欠落オペランド」エラーが発生しました。ちょっとめちゃくちゃ。すでに約1時間を費やしました。 "yamlの代わりにすべてをrm"してください...誰でもバグを見つけたり、修正を提案したりできますか?

私も #!/bin/sh と #!/bin/bash を試しました。少しでも効果がないかと思いました。

ベストアンサー1

!(x)Korn シェルグローバル演算子です。この演算子を含むが1以降にのみサポートされるglob演算子bashのサブセット。kshshopt -s extglob

だから:

shopt -s extglob
rm -f -- !(*.yaml)

名前が . で終わるファイルを除き、現在のディレクトリから隠されていないすべてのファイルが削除されます.yaml

とにかくグローバルオペレーターはいいえ引用時にそのように認識されるので\(Bourneシェルの引用演算子の1つ)を使用することは役に立ちません。

シェルでこれに対応するものは次のとおりですzsh

rm -f -- ^*.yaml

これを行うにはset -o extendedglob

(または!(x)それ以降もサポートされます)。emulate kshset -o kshglob

sh拡張機能を使用してサポートshに基づく実装など、いくつかの実装を見つけることができますが、言語には同等の実装はありません。ksh!(x)


¹これはシェルの解析に影響を与えるため、shoptコマンドを実行する必要があります。今後これらのkshスプレッド演算子の1つを含む行は次のとおりです。読むそして解析します。たとえば、bash -c 'shopt -s extglob; echo !(x)'行全体が最初に解析された後(extglobがまだ開かれていない)shopt実行(まあ、構文エラーがなかった場合は実行された)となるため、構文エラーが発生します。bash -O extglob -c 'echo !(x)'とても良いです。

おすすめ記事