编写Bash脚本遍历目录用tar压缩指定文件夹,如何去父路径并自定义输出位置
问题核心原因
- 原脚本中使用了
--absolute-names参数,会强制保留文件从系统根目录开始的完整绝对路径,导致压缩包内出现/MyPersonalFolder/0001/0001/WhatIWantFolder这类冗余路径 - 之前尝试替换tar源路径时报错,本质是没有指定tar的参考工作目录:直接传入相对的数字目录名时,tar默认在当前执行脚本的工作目录下查找文件,自然无法匹配到对应路径
- 原脚本中mv部分存在文件名不匹配的bug:实际生成的压缩包名为
{编号}-WhatIWantFolder.tar.gz,但mv目标写的是{编号}-theme.tar.gz,移动操作实际不会生效
可直接使用的调整方案
核心思路是利用tar的-C参数切换打包时的参考工作目录,直接在tar命令中指定自定义的压缩包输出路径,完全去掉冗余路径,同时解决相对路径找不到的问题:
- 移除导致冗余全路径的
--absolute-names参数 - 提前定义可灵活修改的配置项,包括遍历根目录、自定义压缩包输出位置、要打包的目标子文件夹名
- 对每个匹配到的目标文件夹,拆解出打包需要的基准参考目录,通过
-C参数让tar在该参考目录下执行相对路径打包,保证压缩包内的路径结构完全符合要求 - 修正原脚本中文件名不匹配的bug,省去事后移动文件的冗余步骤
调整后的完整脚本:
#!/bin/bash # 自定义配置区,可按需修改 TRAVERSE_ROOT="/MyPersonalFolder" # 需要遍历的根目录 OUTPUT_DIR="./backup-theme" # 自定义压缩包存储位置 TARGET_FOLDER="WhatIWantFolder" # 需要打包的目标子目录 # 提前创建输出目录,避免打包时报路径不存在的错误 mkdir -p "$OUTPUT_DIR" for dir in "$TRAVERSE_ROOT"/*/*/"$TARGET_FOLDER" do # 拆解路径:找到目标文件夹的直接上级目录(即带数字编号的文件夹) target_parent=$(dirname "$dir") folder_number=$(basename "$target_parent") # 拆解路径:找到打包的基准参考目录(即数字编号文件夹的上级目录) archive_base=$(dirname "$target_parent") # 执行打包:在基准参考目录下,打包"数字编号/WhatIWantFolder"的相对路径 sudo tar -czf "$OUTPUT_DIR/${folder_number}-${TARGET_FOLDER}.tar.gz" \ -C "$archive_base" \ "${folder_number}/${TARGET_FOLDER}" done
实现效果验证
- 打开生成的压缩包,内部结构直接为
{数字编号}/WhatIWantFolder/原有文件,没有任何从系统根目录开始的冗余父路径 - 所有生成的压缩包会直接存储在你自定义的
OUTPUT_DIR路径下,不需要额外执行移动命令 - 不再出现之前的
Cannot stat: No such file or directory报错:因为tar已经通过-C参数切换到了正确的参考工作目录,相对路径可以被正常识别
注意:如果你的目录结构实际是
/MyPersonalFolder/{数字编号}/WhatIWantFolder(少嵌套一层),只需要把循环里的路径通配符从"$TRAVERSE_ROOT"/*/*/"$TARGET_FOLDER"改成"$TRAVERSE_ROOT"/*/"$TARGET_FOLDER"即可,其余逻辑不需要修改。
内容的提问来源于stack exchange,提问作者Said Metagle
相关产品推荐
相关产品推荐

