如何从 bash 中的文件名扩展机制中排除某些文件?

如何从 bash 中的文件名扩展机制中排除某些文件?

我的根目录中有 ubuntu 文件系统目录,并且我不小心将数百个文件复制到根目录中。

我直观地尝试通过排除文件系统来删除复制的文件,例如

rm -rf !{bin,sbin,usr,opt,lib,var,etc,srv,libx32,lib64,run,boot,proc,sys,dev} ./.

但它不起作用。在删除整个目录时排除某些目录的正确方法是什么?

编辑:在不知道该怎么做的情况下,切勿尝试此处的任何命令!

答案1

由于您正在使用bash

shopt -s extglob
echo rm -rf ./!(bin|sbin|usr|...)

echo我建议当您运行某些可能会炸毁整个系统的东西时在命令行的开头添加。如果您对结果满意,请将其删除。

注意:上述命令不会删除隐藏文件(名称以点开头的文件)。如果您还想删除它们,请同时激活dotglob选项:

shopt -s dotglob

答案2

此命令将显示以下位置的所有非目录/

find / -maxdepth 1 -type f

一旦你做了绝对地确保没有您想要保留的文件,您可以使用:

find / -maxdepth 1 -type f -delete

更安全的方法是将它们移到其他地方,以确保您不会删除要保留的内容:

mkdir /root/preserve
find / -maxdepth 1 -type f -exec mv -- "{}" /root/preserve/\;

如果除了文件之外,您还有目录您已添加到文件系统的根目录,这可以通过从自动mv或中排除 LSB 目录来实现自动化rm,但老实说,由于我们正在处理清除文件系统根目录中的内容,因此我强烈建议您考虑手动执行此操作(如果可行)。

如果这不可行,类似这样的事情可以解决问题:

#!/bin/bash
declare -a excludes
for item in root sys 'lost+found' mnt home proc etc opt boot lib lib64 libx32 sbin media srv dev var usr bin tmp run; do
    excludes+=("$item")
done
if ! [[ -d /root/preserve ]]; then
    mkdir -p /root/preserve
fi
IFS="\n"
for item in find / -type d -maxdepth 1; do
    really=true
    for exclude in ${excludes[@]}; do
        if [[ "$exclude" == "${item#/}" ]]; then
            really=false
        fi
    done
    if [[ "true" == "$really" ]]; then
        mv -- "$item" /root/preserve/
    fi
done

一旦您通过了尖叫测试(即您的系统仍在运行并且您没有痛苦地尖叫),您就可以删除 的内容/root/preserve/

重要提示:无论您做什么,都不要考虑运行rm -fr [ANYTHING GOES HERE] /.

答案3

这应该可以完成工作(尽管与OP要求的方式不同):

ls -1 >1.txt
pico 1.txt 

删除您要保留的所有文件/目录

xargs rm < 1.txt

如果您的文件都具有相同的名称格式、日期或其他内容,那么还有其他方法。

我会查看索引节点 - 看看它们是否是连续的ls -i |排序如果是,那么新文件将具有更大的索引节点。然后使用与上面相同类型的过程......

ls -iF1 | sort |cut -c10- | grep -vE "\/|\@" >i.txt   #This part removes entries that are not regular files, such as directories and links.  
pico i.txt
xargs rm < i.txt

在上面的 cut 命令中,首先检查您的 inode 列表以确保其数量正确。

相关内容