如何压缩foo包时排除父目录?避免包内文件扁平化的Zip方案
解决Zip压缩时保留目标文件夹结构但去除上层目录的问题
我明白你的痛点——既要保留.foo文件夹本身的完整结构,又不想把root/subroot/subsubroot这些上层目录带进压缩包,之前的命令要么带全路径,要么把文件夹里的文件扁平化,确实挺闹心的!
这里给你几个靠谱的解决方案,最终都会生成符合需求的Zip包:
方法1:切换到目标目录后压缩(最直观易理解)
核心思路是先进入存放.foo文件夹的目标目录,再执行压缩命令,这样Zip只会记录当前目录下的相对路径,不会带上层结构:
# 切换到目标目录 cd root/subroot/subsubroot # 查找所有*.foo文件夹(排除名称含somestring的),并压缩到上级目录的foos.zip find . -name '*.foo' -type d ! -name '*somestring*' | xargs zip -r ../foos.zip # 想回到原来的目录,执行这条命令即可 cd -
细节解释:
find . -name '*.foo' -type d:只查找当前目录下的.foo类型文件夹(避免误匹配同名文件)! -name '*somestring*':直接排除名称包含somestring的文件夹,省去单独的grep步骤zip -r ../foos.zip:把找到的文件夹递归压缩到上级目录的foos.zip中,压缩包内的路径会是./file1.foo这类,解压后直接得到完整的.foo文件夹,没有多余层级。
方法2:不改变当前工作目录的脚本友好版
如果是在脚本里执行,不想打乱当前工作目录,可以用pushd和popd临时切换目录:
# 临时切换到目标目录,屏蔽冗余输出 pushd root/subroot/subsubroot > /dev/null # 执行压缩操作 find . -name '*.foo' -type d ! -name '*somestring*' | xargs zip -r ../foos.zip # 切回原工作目录,屏蔽冗余输出 popd > /dev/null
方法3:用Tar中转后转Zip(适合习惯Tar语法的场景)
如果你更熟悉Tar的参数,也可以先打包再转成Zip格式,效果完全一致:
tar -c -C root/subroot/subsubroot --exclude='*somestring*' -f - *.foo | zip foos.zip -@
细节解释:
tar -C root/subroot/subsubroot:告诉Tar先切换到目标目录再打包--exclude='*somestring*':直接排除不需要的文件夹-f -:把Tar包内容输出到标准输出zip foos.zip -@:Zip从标准输入读取要压缩的文件名列表,最终生成的Zip包只会包含.foo文件夹本身。
为什么之前的命令不符合需求?
- 你原来的
find root/subroot/subsubroot会输出完整路径(比如root/subroot/subsubroot/file1.foo),Zip会把这个完整路径全部加入包内,所以解压后会带层级; -j选项是"junk paths"(丢弃路径),会把所有文件从.foo文件夹里提取出来直接放在Zip根目录,破坏了文件夹的原有结构,自然不符合要求。
内容的提问来源于stack exchange,提问作者user9363939
相关产品推荐
相关产品推荐

