我跑这个脚本但这在提取 rar 多部分时存在问题
#!/usr/bin/env bash
shopt -s extglob nullglob
passw=(
passfoo
passbar
passfoobar
banana
chocolate
whiskey
vodka
icecream
)
for f in *.@(rar|zip|zip.001|7z|7z.001); do
for p in "${passw[@]}"; do
if 7z x -y -p"$p" "$f" -aoa; then
break
fi
done
done
使用.zip
或.7z
可以很好地解压缩多部分,因为多部分的扩展名是相等的(对于.7z
= 7z.001
,7z.002
等。对于.zip
= zip.001
,zip.002
等)。问题是,如果我将其添加到脚本中:
*.@(rar|part1.rar|zip|zip.001|7z|7z.001)
它失败是因为*.partX.rar
和.rar
都以.rar并且循环一遍又一遍地解压同一个文件,.part2.rar
如果文件有密码,则继续失败
修复该问题的尝试失败:
要排除任何文件
.part2.rar
(例如*.part{2..99}.rar
:)随着开关“-x”
我很感激帮助完成循环并集成.rar
格式中的多部分文件的解压缩
答案1
外循环中要做的第一件事可能是检查是否$f
有资格跳过。
在 Bash 中,您可以使用 来执行此操作[[
,使用模式匹配(使用=
、==
或!=
)或正则表达式(使用=~
)。后者选项更强大。对于您的情况,这应该有效:
for f in *.@(rar|zip|zip.001|7z|7z.001); do
[[ ( "$f" =~ \.part[[:digit:]]+\.rar$ ) && ! ( "$f" =~ \.part0*1\.rar$ ) ]] && continue
for p …
我使用的表达方式由以下部分组成:
\.
– 匹配文字点part
,rar
,1
– 这些分别与part
、rar
和1
字面意思匹配[[:digit:]]+
– 匹配一个或多个数字(由当前语言环境定义)0*
– 匹配零个或多个0
字符$
– 匹配被测试字符串的结尾
!
否定。
逻辑是这样的:如果文件名以 结尾.part<digit(s)>.rar
并且不以 结尾.part1.rar
(或.part01.rar
,或.part001.rar
等),则恢复下一次迭代(即采取下一次f
并重新开始)。
如果我是你,我会nocaseglob
在该shopt -s …
行中添加,以将类似名称FOO.RAR
与你的模式 ( *.@(rar|zip|zip.001|7z|7z.001)
) 进行匹配。我的测试表明,这足以使我的解决方案 ( =~
) 也能与它们配合使用(无需另外启用nocasematch
)。
shopt -s extglob nullglob nocaseglob