原始输入:
➜ test tree
.
├── f1.md
├── f2.md
├── f3.md
├── f4.txt
├── f5.csv
├── f6.doc
├── s1
│ ├── code
│ └── data
│ ├── f1.md
│ ├── f2.md
│ ├── f3.md
│ ├── f4.txt
│ ├── f5.csv
│ └── f6.doc
├── s2
│ ├── code
│ └── data
│ ├── f1.md
│ ├── f2.md
│ ├── f3.md
│ ├── f4.txt
│ ├── f5.csv
│ └── f6.doc
├── s3
│ ├── code
│ └── data
│ ├── f1.md
│ ├── f2.md
│ ├── f3.md
│ ├── f4.txt
│ ├── f5.csv
│ └── f6.doc
└── s4
├── code
└── data
├── f1.md
├── f2.md
├── f3.md
├── f4.txt
├── f5.csv
└── f6.doc
12 directories, 30 files
预期产出
➜ test tree
.
├── f1.md
├── f2.md
├── f3.md
├── f4.txt
├── f5.csv
├── f6.doc
├── s1
│ ├── code
│ └── data
│ ├── Archive.zip
│ ├── f1.md
│ ├── f2.md
│ ├── f3.md
│ ├── f4.txt
│ ├── f5.csv
│ └── f6.doc
├── s2
│ ├── code
│ └── data
│ ├── Archive.zip
│ ├── f1.md
│ ├── f2.md
│ ├── f3.md
│ ├── f4.txt
│ ├── f5.csv
│ └── f6.doc
├── s3
│ ├── code
│ └── data
│ ├── f1.md
│ ├── f2.md
│ ├── f3.md
│ ├── f4.txt
│ ├── f5.csv
│ └── f6.doc
└── s4
├── code
└── data
├── Archive.zip
├── f1.md
├── f2.md
├── f3.md
├── f4.txt
├── f5.csv
└── f6.doc
12 directories, 33 files
我想要压缩子文件夹(s1/s2/s4)中的文件。
zip -r Archive.zip ./*
我尝试在每个子文件夹( s1/s2/s4) 中使用命令行。这很不方便,因为我必须输入相同的命令三次。
如何使用一次命令或编写脚本来实现此目的?我使用的是 OSX(10.12.6)。
答案1
find . -type d -name data -execdir zip -jr data/Archive.zip data ';'
该find
命令会查找data
当前目录下的各个目录并执行
zip -jr data/Archive.zip data
在每个sN
目录(目录的父目录data
)中。这也将归档隐藏文件。
标志-j
tozip
将删除添加到存档中的文件的路径名,并且存档将放置在data
目录内。
这是有效的,因为-execdir
基本上cd
在执行命令之前会对找到的东西的父目录执行 a 操作。
要避免该s3
目录,请使用
find . -type d -name data \! -path "./s3/*" -execdir zip -jr data/Archive.zip data ';'
答案2
像这样的脚本可以完成这项工作:
for i in `find /path -type d -name data`;
do
if [ "$i" = "s3/data" ]
then continue
else cd "$i" && zip Archive.zip *
fi
done
PS 替换/path
为目录树的起点
答案3
POSIXly(显然命令除外zip
):
find . -path ./s3 -prune -o -type d -name data -exec sh -c '
for dir do
(cd "$dir" && zip -r Archive.zip .)
done' sh {} +
或者与zsh -o extendedglob
:
for dir (./**/data~*/s3/*(/N)) (cd $dir && zip -r Archive.zip .)
或者,如果您不想递归搜索data
文件夹:
for dir (./^s3/data(/N)) (cd $dir && zip -r Archive.zip .)
或者更具体(这里不需要extendedglob
):
for dir (s[124]/data(/N)) (cd $dir && zip -r Archive.zip .)