简体   繁体   English

GNU/Linux - 正确使用“zip”命令来展平子目录?

[英]GNU/Linux - proper use of the 'zip' command to flatten the subdirectories?

I'm looking for some help in properly using the zip command in GNU/Linux systems.我正在寻找在 GNU/Linux 系统中正确使用zip命令的帮助。 Let's say I have this directory structure (the actual use case is more complex, but this is a simplified example):假设我有这个目录结构(实际用例更复杂,但这是一个简化的例子):

Documents
└── foo1
    └── foo2
        ├── foo3a 
        │   └──foo4
        │      ├──file1.txt
        │      └──file2.py
        └── foo3b
            └──foo4
               ├──file3.txt
               └──file4.py

I want to make a zip file that only includes the txt files.我想制作一个仅包含txt文件的 zip 文件。 And ideally I want it to be part of a bash script running from the Documents location.理想情况下,我希望它成为从Documents位置运行的 bash 脚本的一部分。 So, referencing the documentation of the zip function I naively start with:因此,参考zip function 的文档,我天真地开始:

cd ~/Documents
zip -r foo . -i foo1/foo2/*/foo4/*.txt 

This does zip up all the txt files, but the resulting foo.zip file has the full directory structure (foo1 -> foo2 -> foo3a/foo3b, etc...).这确实 zip 所有txt文件,但生成的foo.zip文件具有完整的目录结构(foo1 -> foo2 -> foo3a/foo3b,等等...)。

zip文件夹结构

I'd like to "flatten" it so that the foo.zip structure starts at foo2, even though the command is being run in ~/Documents .我想“展平”它,以便foo.zip结构从 foo2 开始,即使该命令正在~/Documents中运行。 The examples in the documentation all use the .文档中的示例都使用. as the inpath variable.作为inpath变量。 So I try changing it to where I want foo.zip to start:所以我尝试将其更改为我希望foo.zip开始的位置:

zip -r foo ./foo1/foo2 -i foo1/foo2/*/foo4/*.txt

But foo.zip still has the full directory path of foo1 -> foo2, etc... Even if I run但是foo.zip仍然有 foo1 -> foo2 等的完整目录路径......即使我运行

zip -r foo ./foo1/foo2/foo3a -i foo1/foo2/*/foo4/*.txt

It will only zip up file1.txt from foo3a , but the full directory structure remains.它只会从 foo3a 向上file1.txt foo3a ,但完整的目录结构仍然存在。 So the inpath variable only determines where the search for files starts from, not where the eventual zip directory starts from.所以inpath变量只决定文件搜索从哪里开始,而不是最终的 zip 目录从哪里开始。 I've tried other various versions of the zip command but I can't get the outcome I'm looking for.我已经尝试了 zip 命令的其他各种版本,但无法获得所需的结果。 Is there any way of using the zip command to result in a foo.zip of:有什么方法可以使用zip命令生成foo.zip

foo.zip
├── foo3a 
│   └──foo4
│      ├──file1.txt
│      └──file2.py
└── foo3b
    └──foo4
       ├──file3.txt
       └──file4.py

Or even possibly flattening the downstream folders (since foo4 is common to both) to something like:或者甚至可能将下游文件夹(因为foo4对两者都是通用的)展平为:

foo.zip
├── foo3a 
│   └──file1.txt
│   └──file2.py
└── foo3b
    └──file3.txt
    └──file4.py

How would one do this?如何做到这一点? I also tried using the -j option:我还尝试使用-j选项:

zip -rj foo . -i foo1/foo2/*/foo4/*.txt
>> zip warning: zip file empty

Does this do what you want?这会做你想要的吗?

cd ~/Documents
(cd foo1/foo2; zip -r - . -i '*.txt') >foo.zip
  • (...) creates a subshell where a cd won't affect the top-level shell. (...)创建一个子 shell,其中cd不会影响顶级 shell。
  • Specifying an archive path of - causes the archive to be written to standard output.指定存档路径-会使存档写入标准 output。
  • The >foo.zip causes the archive date to be written to the file foo.zip in the current directory for the top-level shell ( ~/Documents ). >foo.zip导致归档日期被写入文件foo.zip在顶级 shell ( ~/Documents ) 的当前目录中。
zip -r --include '*.txt' -j foo.zip .

The -r traverses the whole tree. -r 遍历整棵树。

The --include restricts the selection to txt files. --include 将选择限制为 txt 文件。

The -j stores the files only under their name, with no path information. -j 仅将文件存储在它们的名称下,没有路径信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM