Sudo rm -r
を使用する場合、次の例外を除き、すべてのファイルを削除するにはどうすればよいですか:
textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete
-type f
を指定しない場合、findはディレクトリを一覧表示しますが、これは望まないかもしれません。
または、非常に便利な組み合わせfind | xargs
を使用したより一般的なソリューション:
find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm --
たとえば、現在のディレクトリにあるすべての非txtファイルを削除します。
find . -type f -not -name '*txt' -print0 | xargs -0 rm --
削除するファイル名にスペースがある場合は、print0
と-0
の組み合わせが必要です。
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)
Extglob(拡張パターンマッチング)は、BASHで有効にする必要があります(有効になっていない場合)。
shopt -s extglob
find . | grep -v "excluded files criteria" | xargs rm
これにより、現在のディレクトリ内のすべてのファイルが一覧表示され、次に条件に一致しないすべてのファイルが一覧表示され(ディレクトリ名と一致することに注意して)、それらが削除されます。
更新:編集に基づいて、リストしたファイル以外のすべてを現在のディレクトリから本当に削除したい場合、これを使用できます:
mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup
バックアップディレクトリ/tmp_backup
を作成し(ルート権限を持っていますか?)、リストしたファイルをそのディレクトリに移動し、現在のディレクトリのすべてを再帰的に削除します(正しいディレクトリにいることを知っていますか?)、 /tmp_backup
のすべてを現在のディレクトリに戻し、最後に/tmp_backup
を削除します。
ルートからすべてを再帰的に削除しようとすると、システムに大きな問題が発生するため、バックアップディレクトリをルートに選択します。
これを行うためのよりエレガントな方法は確かにありますが、これは非常に簡単です。
BashでGLOBIGNORE環境変数を使用できます。
Phpとsqlを除くすべてのファイルを削除する場合、次の操作を実行できます-
export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=
このようにGLOBIGNOREを設定すると、「ls *」や「rm *」などのワイルドカードからのphpとsqlが無視されます。したがって、変数の設定後に「rm *」を使用すると、txtファイルとtar.gzファイルのみが削除されます。
これらの名前のファイルがディレクトリツリーの複数の場所に存在し、それらすべてを保持すると仮定します。
find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete
私はサブクエリリストを使用することを好みます:
rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`
-v、-invert-match一致しない行を選択
\|
セパレーター
誰も言及していないので:
OPには少し遅れましたが、Googleで後日ここにたどり着く人にとってはうまくいけば便利です...
@awiの回答を見つけ、@ Jamie Bullockの-deleteについてコメントしました。最小限の入力で毎回異なるファイル名/タイプを無視して、異なるディレクトリでこれを実行できるシンプルなユーティリティ:
rm_except(または名前を付けたいもの)
#!/bin/bash
ignore=""
for fignore in "$@"; do
ignore=${ignore}"-not -name ${fignore} "
done
find . -type f $ignore -delete
例えばテキストファイルとfoo.barを除くすべてを削除するには:
rm_except *.txt foo.bar
@mishunikaに似ていますが、if句はありません。
zsh
を使用している場合、これを強くお勧めします。
rm -rf ^file/folder pattern to avoid
extended_glob
を使用
setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)
このためにforループを記述できます...%)
for x in *
do
if [ "$x" != "exclude_criteria" ]
then
rm -f $x;
fi
done;
それを試してみました:
rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)
しかし、スペースを含む名前は(いつものように)難しいです。引用符の代わりにVirtualbox\ VMs
も試してみました。常にそのディレクトリ(Virtualbox VMs
)を削除します。
ただ:
rm $(ls -I "*.txt" ) #Deletes file type except *.txt
または:
rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf
ファイルを不変にします。 rootでさえそれらを削除することはできません。
chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt
rm *
他のすべてのファイルは削除されました。
最終的には変更可能にリセットできます。
chattr -i *
これを行うには、2つのコマンドシーケンスを使用します。最初に、除外したくないファイルの名前で配列を定義します。
files=( backup.tar.gz script.php database.sql info.txt )
その後、除外したいディレクトリ内のすべてのファイルをループし、ファイル名が除外したくない配列にあるかどうかを確認します。そうでない場合は、ファイルを削除します。
for file in *; do
if [[ ! " ${files[@]} " ~= "$file" ]];then
rm "$file"
fi
done
これは@ siwei-shenのコメントに似ていますが、複数のパターンを実行するには-o
フラグが必要です。 -o
フラグは「または」を表します
find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm