web-dev-qa-db-ja.com

ディレクトリから一部を除くすべてのファイルを削除する

Sudo rm -rを使用する場合、次の例外を除き、すべてのファイルを削除するにはどうすればよいですか:

textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
202
masjoko
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の組み合わせが必要です。

207
awi
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)

Extglob(拡張パターンマッチング)は、BASHで有効にする必要があります(有効になっていない場合)。

shopt -s extglob
148
pl1nk

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を削除します。

ルートからすべてを再帰的に削除しようとすると、システムに大きな問題が発生するため、バックアップディレクトリをルートに選択します。

これを行うためのよりエレガントな方法は確かにありますが、これは非常に簡単です。

39
darioo

BashでGLOBIGNORE環境変数を使用できます。

Phpとsqlを除くすべてのファイルを削除する場合、次の操作を実行できます-

export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=

このようにGLOBIGNOREを設定すると、「ls *」や「rm *」などのワイルドカードからのphpとsqlが無視されます。したがって、変数の設定後に「rm *」を使用すると、txtファイルとtar.gzファイルのみが削除されます。

19
theharshest

これらの名前のファイルがディレクトリツリーの複数の場所に存在し、それらすべてを保持すると仮定します。

find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete
18

私はサブクエリリストを使用することを好みます:

rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`

-v、-invert-match一致しない行を選択

\|セパレーター

15
Nick Tsai

誰も言及していないので:

  • 削除したくないファイルを安全な場所にコピーします
  • すべてのファイルを削除する
  • コピーしたファイルを元の場所に戻す
9
gniourf_gniourf

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句はありません。

6

zsh を使用している場合、これを強くお勧めします。

rm -rf ^file/folder pattern to avoid

extended_globを使用

setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)
5
sudo bangbang

このためにforループを記述できます...%)

for x in *
do
        if [ "$x" != "exclude_criteria" ]
        then
                rm -f $x;
        fi
done;
5
mishunika

それを試してみました:

rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)

しかし、スペースを含む名前は(いつものように)難しいです。引用符の代わりにVirtualbox\ VMsも試してみました。常にそのディレクトリ(Virtualbox VMs)を削除します。

4
juanfal

ただ:

rm $(ls -I "*.txt" ) #Deletes file type except *.txt

または:

rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf
4
wyx

ファイルを不変にします。 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
0

これは@ siwei-shenのコメントに似ていますが、複数のパターンを実行するには-oフラグが必要です。 -oフラグは「または」を表します

find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm

0
Daniel Chen