删除与列表不匹配的文件夹

删除与列表不匹配的文件夹

我需要实际的例子如何删除不在 Linux 列表中的文件夹。所以我不需要比较它的内容或 md5sums,只需比较文件夹名称。

例如一个文件夹里面有几个文件夹

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

我的文件夹名称列表是txt文件,包括folder1、folder2,不包括folder3和folder4。

如何通过bash脚本删除folder3和folder4?

这已在 serverfault 上得到回答

GLOBIGNORE=folder1:folder2
rm -r *
uset GLOBIGNORE

但我真正的任务是删除一堆文件夹。 txt 列表包含大约 100 个文件夹,要清理的目标文件夹是 200 个文件夹。

请注意,这应该在 Linux 和 FreeBSD 中都有效。

编辑: target_folder 可能包含带有子文件夹的文件夹以及文件。没有空格和前导点以及名称不相似:foo.com bar.org emptydir file.txt simplefile。但除列表中的名称外,所有这些项目都应删除。

第一个答案更加明显和简单。第二个更高级和灵活,它也允许您根据项目类型进行删除。

答案1

假设您的文件名不包含任何:\[*?,您仍然可以使用GLOBIGNORE.只需相应地格式化您的目录列表即可。例如:

$ cat names.txt
folder1
folder3

这很容易转换为冒号分隔的列表:

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

因此,您现在可以将其设置为 GLOBIGNORE 的值:

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

并继续正常删除它们:

rm -r -- *

我刚刚在 Linux 上用 300 个目录测试了它,它运行得很好。

答案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

你可以在 bash 中这样做

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

相关内容