You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何删除library目录下未在filenames.txt中列出的子目录?

问题解决:删除library下未在filenames.txt中列出的子目录

原脚本的问题在于循环变量$file是带完整路径的字符串(比如library/ABC),但filenames.txt里只存了纯目录名(比如ABC),所以grep永远匹配不到任何内容,导致所有library/*的条目都被执行rm -r删除。

以下是几种修复后的解决方案:

方案1:提取目录名后精准匹配

修改脚本,先用basename提取纯目录名,再用锚定正则确保整行匹配,同时只处理目录避免误删文件:

for dir in library/*                                               
do
    # 跳过非目录条目
    [ -d "$dir" ] || continue
    # 提取纯目录名
    dir_name=$(basename "$dir")
    # 精准匹配filenames.txt中的整行内容
    grep "^$dir_name$" filenames.txt &> /dev/null || rm -r "$dir"
done

方案2:用固定字符串匹配更安全

如果目录名包含正则特殊字符(比如.、*),用grep -F做固定字符串匹配更稳妥:

for dir in library/*                                               
do
    [ -d "$dir" ] || continue
    dir_name=$(basename "$dir")
    # -F: 固定字符串匹配;-x: 整行匹配;-q: 静默不输出结果
    grep -Fxq "$dir_name" filenames.txt || rm -r "$dir"
done

方案3:预加载允许列表(适合大量子目录场景)

如果library下子目录很多,先把允许的目录名加载到数组,循环判断效率更高:

# 读取filenames.txt内容到数组,跳过空行
mapfile -t allowed_dirs < <(grep -v '^$' filenames.txt)

for dir in library/*
do
    [ -d "$dir" ] || continue
    dir_name=$(basename "$dir")
    # 检查是否在允许列表内
    found=0
    for allowed in "${allowed_dirs[@]}"; do
        [ "$allowed" = "$dir_name" ] && found=1 && break
    done
    # 不在列表则删除
    [ $found -eq 0 ] && rm -r "$dir"
done

重要提醒

  • 测试阶段先把rm -r换成echo rm -r,确认要删除的目录正确后再执行实际删除操作
  • 操作前务必备份library目录下的重要数据,避免误删
  • 如果filenames.txt中有带空格的目录名,上述脚本因使用双引号包裹变量,能正确处理这种情况

内容的提问来源于stack exchange,提问作者Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:12:16