我正在尝试根据某些正则表达式压缩 dir 中的所有文件夹,因此我使用 grep 来过滤输出,现在我需要使用 tar 和文件夹名称。
例如,我想将每个顶级目录 .tar.gz 到其自己的存档中。目录名称必须以“web_”开头,不能以“.tar.gz”结尾。
如何将 grep 输出捕获到 varibel,使其看起来像这样:
find . -maxdepth 1 -mindepth 1 -type d -print | grep -v \.tar\.gz$ | grep ^\./web_ | exec tar -czf $name.tar.gz $name
或使用 ls -h
ls -h | grep -v \.tar\.gz$ | grep ^web_ | exec tar -czf $name.tar.gz $name
选择“查找...”:
root@4a94aef49e3a:/home# find . -maxdepth 1 -mindepth 1 -type d -print | grep -v \.tar\.gz$ | grep ^web_
./web_demozip1
./web_demozip2
选择“ls -h”:
root@4a94aef49e3a:/home# ls -h | grep -v \.tar\.gz$ | grep ^web_
web_demozip1
web_demozip2
例子:
# fixed name works but its overwrite itself so I need to catch a var from grep
ls -h | grep -v \.tar\.gz | grep ^_web | exec tar -czf web_demozip1.tar.gz web_demozip1
root@4a94aef49e3a:/home# pwd
/home
root@4a94aef49e3a:/home# tree .
.
├── web_demozip1
│ └── somefile.txt
├── web_demozip1.tar.gz
└── web_demozip2
└── somefile.txt
答案1
您不需要find
使用 来过滤结果grep
。使用 的过滤器功能find
代替。
find . -maxdepth 1 -mindepth 1 -type d \
-name 'web_*' \
-exec tar czf {}.tar.gz {} \;
find
也可以使用 进行过滤regex
,但您的示例不需要它。看这里怎么做。
答案2
如果您只想归档当前目录中的每个目录,每个目录一个 tarball,我会使用 shell 循环:
for dir in ./web_*/; do
tarname=${dir%/}.tar.gz
tar -czf "$tarname" "$dir"
done
glob ( ) 上的尾部斜杠./web_*/
使其仅匹配目录,并且返回${dir%/}
删除了该后缀的字符串,并且像这样调用的目录可能是一个错误。
请注意,我删除了根据后缀检查名称的条件.tar.gz
,因为我们已经只查看目录,而这些可能是文件。如果您确实有这样命名的目录,则可以添加[[ $dir == *.tar.gz/ ]] && continue
为循环中的第一行。 (在 Bash/ksh/zsh 中。)
如果您想要更复杂的模式,请研究 Bash ( shopt -s extglob
) 中的 Ksh 风格的扩展 glob,或 zsh 中 zsh 自己的扩展 glob。
答案3
使用 xargs
我还发现我可以使用 XARGS 不确定这是否是一个好的方法,所以请在评论中告诉我您对此的看法。我很确定我应该使用 @ilkkachu 或 @pLumo 解决方案,但只是为了证明它可以做到:cdate=$(date '+%Y-%m-%d-%H-%M')
ls -h | grep -v \.tar\.gz$ | grep ^web_ | xargs -I {} tar -czf {}_$cdate.tar.gz {}
这会输出:
root@4a94aef49e3a:/home# tree .
.
├── web_demozip1
│ └── somefile.txt
├── web_demozip1_2021-08-23-14-43.tar.gz
├── web_demozip2
│ └── somefile.txt
├── web_demozip2_2021-08-23-14-43.tar.gz
├── web_ spacedir3
│ └── somefile.txt
└── web_ spacedir3_2021-08-23-14-43.tar.gz