嵌套 for 循环

嵌套 for 循环

我正在尝试列出嵌套 zip 中的文件,如下所示。它没有列出第二级文件。

例如:

abc.zip包含test1.zip, test2.zip,test3.zip

pqr.zip包含test4.zip, test5.zip,test6.zip

for f in *.zip
do
  unzip -l ${f}
  for p in ${f}
  do 
    unzip -l ${p}
  done
done

答案1

通过结合 libarchivebsdtar和 GNU tar,您可以列出这些嵌套存档的内容,而无需将它们提取到磁盘上:

for f in *.zip; do
  bsdtar -cf - --include='*.zip' "@$f" | tar -xf - --to-command='bsdtar tvf -'
done

GNUtar可以在提取时通过管道将存档成员传递给命令,--to-command但仅支持tar存档格式。

bsdtar支持各种存档格式tar(包括zip),没有相当于 GNUtar--to-command(据我所知),但可以即时转换存档格式。

答案2

如果不将顶层文件实际解压缩到子文件夹中,您就无法做到这一点。

像这样的东西:

set -e
for f in *.zip
do
  n=`basename -- "${f}" .zip`
  mkdir -- "${n}"
  cd -- "${n}"
  unzip ../"${f}"
  for p in *.zip
  do
    unzip -l -- "${p}"
  done
  cd ..
  rm -rf -- "${n}"
done

您可能应该验证是否${n}已经存在,如果存在则生成错误。您还可以为子目录使用临时文件名:

dir=`mktemp -d zip-files.XXXXXX`

然后做cd "${dir}"rm -rf "${dir}"一旦完成。

更新:

用于set -e确保如果出现问题,脚本会停止。特别是,如果mkdir -- "${m}"失败,则cd -- "${m}"也会失败,因此cd ..会使您进入错误的目录级别,这就是rm -rf -- "${n}"变得危险的地方。

使cd ..语句更安全的另一种方法是在循环之前记住该目录for并使用该路径,如下所示:

topdir=`pwd`
for ...
do
  ...
  cd "$topdir"   # instead of `cd ..`
  ...
done

这样,意志rm -rf -- "${n}"就只能在 中运作$topdir

使用临时目录也会使事情变得更加安全,因为这样无论顶部 zip 文件中的文件名是什么,目录创建/删除都将按预期进行。

答案3

如果安装了 GNU Parallel:

extract_list() {
  mkdir "$1"
  cd "$1"
  unzip ../"$1".zip
  parallel unzip -l ::: *.zip
  cd ..
  rm -rf "$1"
}
export -f extract_list

parallel extract_list {.} ::: *.zip

相关内容