リストと一致しないフォルダの削除

リストと一致しないフォルダの削除

Linuxでリストにないフォルダを削除する方法の実際的な例が必要です。したがって、コンテンツやmd5sumを比較する必要はなく、フォルダ名のみを比較する必要があります。

たとえば、1つのフォルダに複数のフォルダがあります。

target_folder/
├── folder1
├── folder2
├── folder3
└── folder4

私のフォルダ名のリストは、フォルダ1、フォルダ2を含み、フォルダ3とフォルダ4を除くtxtファイルです。

bashスクリプトを使用してフォルダ3とフォルダ4を削除する方法は?

これはserverfaultで回答されました。

GLOBIGNORE=folder1:folder2
rm -r *
uset GLOBIGNORE

しかし、私の実際の使命は、複数のフォルダを削除することです。 txt リストには約 100 個のフォルダが含まれており、整理する対象フォルダは 200 個のフォルダです。

これはLinuxとFreeBSDの両方で動作します。

編集する: target_folderには、ファイルだけでなくサブフォルダを含むフォルダも含めることができます。スペースと先行点と類似していない名前:foo.com bar.orgemptydir file.txt simplefile。ただし、リスト内の名前を除くすべての項目を削除する必要があります。

最初の答えはより明確で簡単です。 2番目はさらに進化し、柔軟性があり、アイテムの種類に応じて削除することもできます。

答え1

ファイル名にが含まれていないと仮定すると、引き続き:\[*?使用できますGLOBIGNORE。そのため、ディレクトリリストの形式を指定できます。たとえば、

$ cat names.txt
folder1
folder3

これはコロンで区切られたリストに簡単に変換されます。

$ paste -s -d : names.txt
folder1:folder3

したがって、GLOBIGNORE値に設定できるようになりました。

GLOBIGNORE=$(paste -s -d : ../names.txt)

正常に削除を進めます。

rm -r -- *

私は300のディレクトリがあるLinuxでテストしましたが、うまくいきました。

答え2

これはどうですか?

find ./target_folder/ \
    -mindepth 1 \
    -maxdepth 1 \
    -type d \
    -not -name 'anything[0-9]*' \
    -exec rm -rf {} \;

説明します。

  • -mindepth 1一致しないことを確認してください。./target_folder/
  • -maxdepth 1一致するサブフォルダがないことを確認してください。
  • -type dファイルではなくディレクトリのみを一致するように find に指示します。
  • -not -name 'anything[0-9]*'パターンに一致するパターンからすべての項目を除外します。どうやら、そうです。
  • -exec特に使用するときは注意してくださいrm。あなたはする必要がありますいつもechoこの方法で進む前にテストしてみてくださいrm -rffind難しいかもしれません
  • \;execを使用するときは、末尾を忘れないでください。

find詳しくはマニュアルページをご覧ください。これはとても便利ツール。

答え3

簡単な方法は、すべてのファイルをリストし、リストファイルのファイルを無視することです。簡単な方法で含めるかどうかを確認ignore_listできるように、変数を改行文字で始めて終了するように配置しました。含めるかどうかを確認するだけでは、無視リストと同じ名前の要素も一致するため、含めるかどうかを確認することは機能しません。$x$ignore_list$x

newline='
'
ignore_list="$newline$(cat list.txt)$newline"
cd target_folder
for x in * .[!.]* ..?*; do
  case "$x" in *"$newline"*) continue;; esac   # sanity check: if the file name contains a newline, leave it alone
  case "$ignore_list" in
    *"$newline$x$newline"*) echo "Skipping $x";;
    *) rm -rf -- "$x";
  esac
done

答え4

バッシュでこれを行うことができます

for folder in /target_folder/*/
do
    folder=${folder%/}
    if ! grep -qx "${folder##*/}" folders_list.txt
    then
        rm -rf "$folder"
    fi
done

関連情報