回答:
おそらく使用すべきシンプルなソリューションは次のとおりです。
mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif
.keep
拡張子について特別なことはありません.gif
。これにより、一時的にファイル名がで終わらないようになります。
ファイルの名前を変更してはいけない場合(およびこれが重要なスクリプトの状況がある場合):
for X in *.gif; do
if [ "$X" != "filename.gif" ]; then
rm "$X"
fi
done
または、次のように短く書くことができます。
for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done
find
代わりに使用することをお勧めします。それは非常に強力であり、あなたはそれをより読みやすくすると思うかもしれません、そして、それらのような文字を持つ奇妙なファイル名を*
より良く処理します。
find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete
-not
読みやすさのために演算子を使用しましたが、POSIX準拠が重要な場合-GNU findを使用していない場合、またはこれが他の人に再配布したり、さまざまなシステムで実行するスクリプト用である場合-する必要があります!
代わりに演算子を使用します。
find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete
便利なことの1つfind
は、大文字と小文字を区別しないようにコマンドを簡単に変更して、次のような拡張子を持つファイルを見つけて削除できる.GIF
ことです。
find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete
私が使用したことに注意してください-iname
の代わりに、-name
検索パターンのための*.gif
が、私はしているではないためにそれを使用filename.gif
。おそらくあなたはあなたのファイルが何と呼ばれているかを正確に知って-iname
おり、拡張子だけでなくファイル名のどこでも代替大文字と一致します。
これらのソリューションはすべて、現在のディレクトリにすぐに存在するファイルのみを削除します。現在のディレクトリに含まれていないファイルは削除しません。また、現在のディレクトリのサブディレクトリにあるファイルも削除しません。
あなたはどこでも、現在のディレクトリに含まれるファイルの削除したい場合は- 、使用(など、あるサブディレクトリを含め、それらのサブディレクトリのサブディレクトリに、ファイルが現在のディレクトリまたはその子孫のいずれかの内に含まれる)find
なし maxdepth -1
:
find . -not -name 'filename.gif' -name '*.gif' -delete
これに注意してください!
を使用して他の値を設定することもできます-maxdepth
。たとえば、現在のディレクトリとその子と孫のファイルを削除し、それよりも深くないファイルを削除するには:
find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete
-delete
他の表現の前に、決して最初に置かないでください!あなたは私がいつも-delete
最後に置いているのを見るでしょう。最初に配置すると、最初に評価され、下にあるすべてのファイル.
(末尾がでない.gif
ファイルやの深いサブサブサブディレクトリ内のファイルを含む.
)が削除されます!
詳細については、のマニュアルページを参照bash
してsh
、これらの例で使用するコマンドのを:mv
、rm
、[
、及び(特に)find
。
find
は非常に汎用性の高いを使用して、別のメソッド(またはメソッドのクラス)に関する情報でこの答えを拡張しました。
find
奇妙なファイル名をどのように扱うの*
ですか?forループは*
、二重引用符を使用したため、ファイルを正常に処理します。
あなたが使用している場合bash
(デフォルトシェル)、extglob
シェルオプションでは、拡張されたパターンマッチング構文を使用することができます。有効にするには、shopt
組み込みコマンドを使用します。
shopt -s extglob
(.bashrc
ファイルにその行を含めます。)
特に、!()
演算子へのアクセスを許可します。これは、括弧内にないパターンに一致します。あなたの目的のために:
rm !(filename).gif
詳細については、man bash
「パターンマッチング」を参照してください。
extglob
有効にする必要がある追加の複雑さがありますが、無効にした場合、悪いことは何も起こりません(その場合、これは機能しません)。そしてshopt -s extglob
、私は自分の(またはグローバルな)設定ファイルのどれも持っていなくても、デフォルトで有効になっているようです。そのまま使用できる理由について簡単な説明がある場合は、この回答に追加してください。または、新しい質問を投稿できます。
GLOBIGNORE
変数があります。からman bash
:
GLOBIGNORE
A colon-separated list of patterns defining the set of filenames
to be ignored by pathname expansion. If a filename matched by a
pathname expansion pattern also matches one of the patterns in
GLOBIGNORE, it is removed from the list of matches.
したがって、簡単な方法はGLOBGINORE
、問題のファイル名に設定するだけです。
$ touch {a,b,c,d}.png
$ echo *.png
a.png b.png c.png d.png
$ GLOBIGNORE=c.png
$ echo *.png
a.png b.png d.png
だから、あなたの場合:
GLOBIGNORE=filename.gif; rm *.gif
もちろん、GLOBIGNORE
パターンが含まれているため、パターンを除外したいときにいつでも使用できます。
$ GLOBIGNORE='[a-c].png'; echo *.png
d.png
$ touch bd.png; GLOBIGNORE='?.png'; echo *.png
bd.png
の利点(?!)GLOBIGNORE
を設定すると、自動的に除外.
および..
一致から除外され、次のことが可能になりますdotglob
。
The GLOBIGNORE shell variable may be used to restrict the set of file‐
names matching a pattern. If GLOBIGNORE is set, each matching filename
that also matches one of the patterns in GLOBIGNORE is removed from the
list of matches. The filenames ``.'' and ``..'' are always ignored
when GLOBIGNORE is set and not null. However, setting GLOBIGNORE to a
non-null value has the effect of enabling the dotglob shell option, so
all other filenames beginning with a ``.'' will match. To get the old
behavior of ignoring filenames beginning with a ``.'', make ``.*'' one
of the patterns in GLOBIGNORE. The dotglob option is disabled when
GLOBIGNORE is unset.
したがって、ディレクトリ内のすべてのファイルとフォルダを削除する簡単な方法:
GLOBIGNORE=.; rm -r *
*
始まるファイル名と一致します.
から、GLOBIGNORE
有効になってdotglob
、それが一致しません.
または..
あなたが道その親ディレクトリには影響しませんので、。