入れ子になった for ループ

入れ子になった for ループ

以下のようにネストされたzipファイルを一覧表示しようとしています。 2 番目のレベルのファイルはリストされません。

たとえば、

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

bsdtarlibarchive と GNU を組み合わせると、tarこれらのネストされたアーカイブの内容をディスクに抽出せずに一覧表示できます。

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

GNUはtar抽出時にアーカイブメンバーをコマンドにパイプできますが、アーカイブ形式--to-commandのみをサポートします。tar

bsdtarさまざまなアーカイブ形式がサポートされていますtar(含まれていますzip)。 GNUと同等のものはありませんがtar--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

関連情報