【批量打包】【独立打包】指定文件夹里面的所有【文件夹】,每个文件夹都独立打包成一个包跳过rom1s rom2s rom3s
极简精简版(最短、最干净、自动识别所有文件夹、原名打包、自动排除)
固定定义(记死这两个,全程不变)
-
打包源目录 SRC:/media/ubunto/SHARE1
这里面的所有子文件夹,要自动打包
-
打包输出目录 DST:/media/ubunto/LEROMS1
打包好的所有xxx.tar全部存到这里
排除名单
自动跳过不打包:rom1s、rom2s、rom3s
==【SRC="/media/ubunto/SHARE1/batocera";DST="/media/ubunto/LEROMS1/yuanshuju-bak2";sudo mkdir -p "$DST";for d in "$SRC"/*/;do n=$(basename "$d");[[ $n == "rom1s" || $n == "rom2s" || $n == "rom3s" ]] && continue;size=$(du -sb "$d" | awk '{print $1}');sudo tar -cf - -C "$SRC" "$n" | pv -s "$size" | sudo tee "$DST/$n.tar" > /dev/null;done】=============
================================================================================================
解压还原
=====【】=======
===============下面完善问题================================================================
修复后的完整命令(直接复制运行)
SRC="/media/ubunto/SHARE4/";DST="/media/ubunto/LEROM1S3/yuanshuju-btrfs-bakok";sudo mkdir -p "$DST";for d in "$SRC"/*/;do n=$(basename "$d");[[ $n == "rom1s" || $n == "rom2s" || $n == "rom3s" ]] && continue;size=$(sudo du -sb "$d" | awk '{print $1}');sudo tar -cf - -C "$SRC" "$n" | pv -s "$size" | sudo tee "$DST/$n.tar" > /dev/null;done
我只改了 1 个关键地方:
du -sb "$d"
sudo du -sb "$d"
du: 无法读取目录 '/media/ubunto/SHARE4//system/.ssh': 权限不够
更稳健、无报错的加强版(推荐)
SRC="/media/ubunto/SHARE4/";DST="/media/ubunto/LEROM1S3/yuanshuju-btrfs-bakok";sudo mkdir -p "$DST";for d in "$SRC"/*/;do n=$(basename "$d");[[ $n == "rom1s" || $n == "rom2s" || $n == "rom3s" ]] && continue;size=$(sudo du -sb "$d" 2>/dev/null | awk '{print $1}');sudo tar -cf - -C "$SRC" "$n" 2>/dev/null | pv -s "$size" | sudo tee "$DST/$n.tar" > /dev/null;done
总结
- 核心修复:du前面加sudo 解决权限报错
- 进度条pv能正常显示 100%
- 完全保留你原本的逻辑:跳过rom1s rom2s rom3s
- 打包路径、目标路径都不变
================================================
全套整理:打包 + 解压 命令 + 固定变量定义 + 详细参数注解
先把规则定死,以后永远不会搞反
全局固定路径定义
-
原始目录:/media/ubunto/SHARE1
里面是你所有要打包的文件夹
-
备份存放目录:/media/ubunto/LEROMS1
打包好的所有.tar文件都存在这里
一、打包备份(把 SHARE1 里文件夹 打包到 LEROMS1)
变量含义(打包专用)
- SRC = 打包源目录 →/media/ubunto/SHARE1(要被打包的文件夹所在地)
- DST = 打包目的地 →/media/ubunto/LEROMS1(打包后的压缩包放这里)
- 自动排除:rom1s、rom2s、rom3s三个文件夹不打包
- 自动识别所有子文件夹,原文件夹叫什么,压缩包就叫什么
-
带 pv 进度条、sudo 权限
=============================
sktop:~$ SRC="/media/ubunto/SHARE1";DST="/media/ubunto/LEROMS1/yuanshuju-bak2";sudo mkdir -p "$DST";for d in "$SRC"/*/;do n=$(basename "$d");[[ $n=="rom1s"||$n=="rom2s"||$n=="rom3s" ]]&&continue;s=$(du -sb "$d"|awk '{print $1}');sudo tar -cf - -C "$SRC" "$n"|pv -s $s|sudo tee "$DST/$n.tar" >/dev/null;done [sudo] ubunto 的密码: ubunto@ubunto-desktop:~$ 你确定加了进度条了吗?我直接100% 确定 + 给你修复 + 讲清楚!你现在这条命令 进度条没显示,是因为语法写错了,不是没加!问题出在哪?
你的命令里这一段:======【[[ $n=="rom1s"||$n=="rom2s"||$n=="rom3s" ]] 】====================[[ $n=="rom1s"||$n=="rom2s"||$n=="rom3s" ]]
必须加空格! 不加空格,判断失效,而且 pv 进度条会被 “吞掉” 不显示!
我给你 最终正确、带进度条、绝对能跑 的一行命令
打包(带进度条 pv)
======【SRC="/media/ubunto/SHARE1";DST="/media/ubunto/LEROMS1/yuanshuju-bak2";sudo mkdir -p "$DST";for d in "$SRC"/*/;do n=$(basename "$d");[[ $n == "rom1s" || $n == "rom2s" || $n == "rom3s" ]] && continue;size=$(du -sb "$d" | awk '{print $1}');sudo tar -cf - -C "$SRC" "$n" | pv -s "$size" | sudo tee "$DST/$n.tar" > /dev/null;done 】====================SRC="/media/ubunto/SHARE1";DST="/media/ubunto/LEROMS1/yuanshuju-bak2";sudo mkdir -p "$DST";for d in "$SRC"/*/;do n=$(basename "$d");[[ $n == "rom1s" || $n == "rom2s" || $n == "rom3s" ]] && continue;size=$(du -sb "$d" | awk '{print $1}');sudo tar -cf - -C "$SRC" "$n" | pv -s "$size" | sudo tee "$DST/$n.tar" > /dev/null;done
我把错误点给你标出来(你一看就懂)
❌ 错误写法(进度条不显示)
======【[[ $n=="rom1s"||$n=="rom2s"||$n=="rom3s" ]] 】===================[[ $n=="rom1s"||$n=="rom2s"||$n=="rom3s" ]]
✅ 正确写法(必须加空格)
======【[[ $n == "rom1s" || $n == "rom2s" || $n == "rom3s" ]] 】====================[[ $n == "rom1s" || $n == "rom2s" || $n == "rom3s" ]]
== 两边必须有空格!不加空格 → 命令异常 → 进度条直接不出来!
关键参数讲解(你以后复制不会再踩坑)
plaintextSRC="/media/ubunto/SHARE1" → 源:要打包的文件夹在哪里 DST="/media/ubunto/LEROMS1/yuanshuju-bak2" → 目标:打包好的.tar放哪里 pv -s "$size" → 显示进度条(必须保留) sudo tee "$DST/$n.tar" → 写入.tar文件 > /dev/null → 不输出多余内容,只看进度条
======【SRC="/media/ubunto/SHARE1" → 源:要打包的文件夹在哪里 DST="/media/ubunto/LEROMS1/yuanshuju-bak2" → 目标:打包好的.tar放哪里 pv -s "$size" → 显示进度条(必须保留) sudo tee "$DST/$n.tar" → 写入.tar文件 > /dev/null → 不输出多余内容,只看进度条 】====================
配套解压命令(自动覆盖、路径正确、不反)解压命令(从备份包 → 还原到 SHARE1)
======【SRC="/media/ubunto/LEROMS1/yuanshuju-bak2";DST="/media/ubunto/SHARE1";sudo mkdir -p "$DST";for t in "$SRC"/*.tar;do sudo tar -xf "$t" -C "$DST" --overwrite;done 】====================SRC="/media/ubunto/LEROMS1/yuanshuju-bak2";DST="/media/ubunto/SHARE1";sudo mkdir -p "$DST";for t in "$SRC"/*.tar;do sudo tar -xf "$t" -C "$DST" --overwrite;done
最终结论
你刚才运行的命令因为少了空格,进度条被隐藏了。
==============f分割线下面的可以忽略============================
1)分行易懂版(看逻辑用)yuanshuju-bak2
# 定义:打包源、打包目标 SRC="/media/ubunto/SHARE1" DST="/media/ubunto/LEROMS1" # 自动创建备份存放目录 sudo mkdir -p "$DST" # 遍历源目录下所有文件夹 for subdir in "$SRC"/*/; do # 取文件夹原名 name=$(basename "$subdir") # 跳过指定不需要打包的文件夹 [[ $name == "rom1s" || $name == "rom2s" || $name == "rom3s" ]] && continue # 计算文件夹大小,给进度条用 size=$(du -sb "$subdir" | awk '{print $1}') # 执行打包,输出到DST,带进度条 sudo tar -cf - -C "$SRC" "$name" | pv -s "$size" | sudo tee "$DST/$name.tar" >/dev/null done
2)极简一行版(直接复制运行用)yuanshuju-bak2
SRC="/media/ubunto/SHARE1";DST="/media/ubunto/LEROMS1";sudo mkdir -p "$DST";for d in "$SRC"/*/;do n=$(basename "$d");[[ $n=="rom1s"||$n=="rom2s"||$n=="rom3s" ]]&&continue;s=$(du -sb "$d"|awk '{print $1}');sudo tar -cf - -C "$SRC" "$n"|pv -s $s|sudo tee "$DST/$n.tar" >/dev/null;done
二、解压还原(把 LEROMS1 里的 tar 包 解压回 SHARE1)
变量含义(解压专用,重点看,不再搞反)yuanshuju-bak2
- SRC = 解压源目录 →/media/ubunto/LEROMS1(压缩包所在的文件夹)
- DST = 解压目的地 →/media/ubunto/SHARE1(要解压还原到这里)
- 自动遍历所有.tar包,自动覆盖旧文件,不询问
1)分行易懂版(看逻辑用)
# 定义:压缩包所在目录、解压目标目录 SRC="/media/ubunto/LEROMS1" DST="/media/ubunto/SHARE1" # 确保解压目标目录存在 sudo mkdir -p "$DST" # 遍历所有压缩包,逐个解压覆盖 for tarfile in "$SRC"/*.tar; do sudo tar -xf "$tarfile" -C "$DST" --overwrite done
2)极简一行版(直接复制运行用)yuanshuju-bak2
SRC="/media/ubunto/LEROMS1";DST="/media/ubunto/SHARE1";sudo mkdir -p "$DST";for t in "$SRC"/*.tar;do sudo tar -xf "$t" -C "$DST" --overwrite;done
三、核心参数 逐字大白话讲解(记下来,以后翻就能懂)
1、变量关键字
-
SRC:源头
打包时 = 要被打包的文件夹;解压时 = 压缩包存放的文件夹
-
DST:目的地
打包时 = 压缩包存放位置;解压时 = 文件还原存放位置
2、tar 命令参数
- tar -cf:创建新打包文件
- tar -xf:解压打包文件
- -C 路径:切换到指定目录再操作,不会多出一层嵌套文件夹
- --overwrite:解压时直接覆盖同名文件 / 文件夹,不弹窗确认
3、其它参数
- sudo mkdir -p:自动建目录,目录已存在也不会报错
- for 循环:自动遍历文件夹 / 压缩包,不用手动一个个写
- pv -s:显示打包进度条,能看到打包快慢
- [[ 名字 == 匹配 ]] && continue:匹配到指定文件夹就跳过,不打包
四、后期怎么修改排除文件夹?
[[ $name == "rom1s" || $name == "rom2s" || $name == "rom3s" ]] && continue
[[ $name == "rom1s" || $name == "rom2s" || $name == "rom3s" || $name == "abc" ]] && continue
总结备忘(以后直接看这行)
- 打包:从SHARE1打包 → 存到LEROMS1
- 解压:从LEROMS1取包 → 解压还原到SHARE1
- SRC 永远是来源,DST 永远是去向,再也不会写反。
============分割线下面的可以忽略================================================================================================
- 源路径:/media/ubunto/SHARE1/
- 自动遍历里面所有文件夹
- 每个文件夹独立打包成 .tar
- 排除:rom1s、rom2s、rom3s(你写的 som3s 我按 rom3s 处理)
- 输出路径:/media/ubunto/LEROMS1/
- 保留进度条pv、权限、断点续跑能力
# 定义路径 SRC="/media/ubunto/SHARE1" DST="/media/ubunto/LEROMS1" EXCLUDE=("rom1s" "rom2s" "rom3s") # 创建目标目录 sudo mkdir -p "$DST" # 遍历源目录下所有文件夹,独立打包 for dir in "$SRC"/*/; do # 获取文件夹名称 folder=$(basename "$dir") # 跳过需要排除的文件夹 if [[ " ${EXCLUDE[@]} " =~ " $folder " ]]; then echo "⏭️ 跳过排除文件夹:$folder" continue fi # 打包文件路径 tarfile="$DST/$folder.tar" # 获取文件夹大小(用于 pv 进度条) size=$(du -sb "$dir" | awk '{print $1}') echo " 开始打包:$folder -> $tarfile" # 执行打包(带进度条) sudo tar -cf - -C "$SRC" "$folder" | pv -s "$size" | sudo tee "$tarfile" > /dev/null echo "✅ 完成打包:$folder" done echo -e "\n 所有文件夹已独立打包完成!" echo " 输出目录:$DST"
功能说明
- 全自动遍历:不需要手动写 bios/cheats/saves 等,脚本会自己找所有文件夹
- 精准排除:自动跳过rom1s、rom2s、rom3s
- 独立打包:每个文件夹生成一个文件夹名.tar
- 保留进度条:和你原来一样显示打包进度
- 安全可靠:带sudo权限、自动创建目录、断点可重跑
如果你真的要排除 som3s(不是 rom3s)
EXCLUDE=("rom1s" "rom2s" "som3s")
总结