使用 bash 提取 .rar 多部分

使用 bash 提取 .rar 多部分

我跑这个脚本但这在提取 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.0017z.002等。对于.zip= zip.001zip.002等)。问题是,如果我将其添加到脚本中:

*.@(rar|part1.rar|zip|zip.001|7z|7z.001)

它失败是因为*.partX.rar.rar都以.rar并且循环一遍又一遍地解压同一个文件,.part2.rar如果文件有密码,则继续失败

修复该问题的尝试失败:

  1. 要排除任何文件.part2.rar(例如*.part{2..99}.rar:)

  2. 随着开关“-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– 这些分别与partrar1字面意思匹配
  • [[: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

相关内容