首页 > 解决方案 > 在递归结构中查找特定的文件扩展名并提取它们直到没有剩余

问题描述

我有一个递归的多个文件夹结构。里面有多个zip、img文件。但是当我提取它时,新的 zip、img 文件又出来了。我想为此写一个循环。

扫描整个递归文件夹,找到多个 zip 文件并提取它们。再次提取扫描文件夹后,如果系统发现新的 zip 文件,请一次又一次地提取它,直到文件夹中没有剩余的 zip 文件。

sample.tar.gz
       1.img
           Thefolder
                 samplefolder
                         t.img
       2.img
           samplefolder2
                 different.gz
       3.img
       4.img

其他 img 文件下还有更多文件夹。

我试图为此编写 for 循环,但无法正常工作。提取 1.img 脚本后出现错误。

错误输出:

ID = 277952352

Everything is Ok

Folders: 3
Files: 1
Size:       345424152
Compressed: 671024244
+ rm -f /home/sample/1.img
+ recursiveExtract /home/sample/Thefolder
+ for file in "$path"/*
+ '[' -d /home/sample/Thefolder ']'
+ recursiveExtract /home/sample/Thefolder
Segmentation fault

编码:

#!/bin/bash
set -x


target_file=$1
path="$(realpath "$1")"
recursiveExtract () { # $1=directory
      for file in "$path"/*; do
        if [ -d "$file" ]; then
            recursiveExtract "$file"
        elif [ -f "$file" -a "${file##*.}" = 'img' ]; then
            7z x $file -o$path -r # variation 2
            rm -f "$file" # comment this if you want to keep the zip files.
            recursiveExtract "${file%.img}"
        fi
        b=$(ls $path | grep img | wc -l)
        if [[ "$b" -eq 0 ]]; then
            break
        fi
      done
      for file in "$path"/*; do
        if [ -d "$file" ]; then
            recursiveExtract "$file"
        elif [ -f "$file" -a "${file##*.}" = 'tar' ]; then
            7z x $file -o$path -r # variation 2
            rm -f "$file" # comment this if you want to keep the zip files.
            recursiveExtract "${file%.tar}"
        fi
        c=$(ls $path | grep tar | wc -l)
        if [[ "$c" -eq 0 ]]; then
            break
        fi
      done
      for file in "$path"/*; do
        if [ -d "$file" ]; then
            recursiveExtract "$file"
        elif [ -f "$file" -a "${file##*.}" = 'gz' ]; then
            7z x $file -o$path -r # variation 2
            rm -f "$file" # comment this if you want to keep the zip files.
            recursiveExtract "${file%.gz}"
        fi
        d=$(ls $path | grep gz | wc -l)
        if [[ "$d" -eq 0 ]]; then
            break
        fi
      done
}
recursiveExtract "$1"

我的代码的最新版本:

#!/bin/bash
# set -x

recursiveExtract () { # $1=directory
      path="$(realpath "$1")"
      echo "GZ------------------"
      for file in "$path"/*; do
        if [ -f "$file" -a "${file##*.}" = 'gz' ]; then
            echo "File:" $file
            echo "Path:" $path
            # 7z e "${file%.gz}" -o"$file" # variation 1
            7z x $file -o$path -r -aou # variation 2
            rm -f "$file" # comment this if you want to keep the zip files.
            recursiveExtract "${file%.gz}"
        fi
        # d=$(ls $path | grep gz | wc -l)
        d=$(find $path -type f -name "*.gz" | wc -l)
        echo "WC GZ-----------------:" $d
        if [[ "$d" -eq 0 ]]; then
            break
        fi
      done
      echo "IMG------------------"
      for file in "$path"/*; do
        if [ -f "$file" -a "${file##*.}" = 'img' ]; then
            echo "File:" $file
            echo "Path:" $path
            # 7z e "${file%.img}" -o"$file" # variation 1
            7z x $file -o$path -r -aou # variation 2
            rm -f "$file" # comment this if you want to keep the zip files.
            recursiveExtract "${file%.img}"
        fi
        # b=$(ls $path | grep img | wc -l)
        b=$(find $path -type f -name "*.img" | wc -l)
        echo "WC IMG-----------------:" $b
        if [[ "$b" -eq 0 ]]; then
            break
        fi
      done
}
while true
do
    d=$(find $1 -type f -name "*.gz" | wc -l)
    b=$(find $1 -type f -name "*.img" | wc -l)
    if [[ "$d" -eq 0 ]] && [[ "$b" -eq 0 ]]; then
        break
    else
        recursiveExtract "$1"
    fi
done

标签: linuxbashshellrecursionunzip

解决方案


这应该做的工作

#!/bin/bash
find ./ -name "*.zip*" > current_zips.txt
while [[ `wc -l "current_zips.txt" | cut -d' ' -f1` > 0 ]]; do
    find ./ -name "*.zip*" -exec unzip {} \;
    while IFS= read file_; do rm $file_; done < "current_zips.txt" # for file_ in $(cat current_zips.txt);do rm $file_;done
    find ./ -name "*.zip*" > current_zips.txt
done

使用以下脚本生成测试数据

#!/bin/bash
#create some data
echo "data 0" > file0.txt
mkdir folder1 folder2
echo "data 1" > folder1/file1.txt
echo "data 2" > folder2/file1.txt
#zip data
zip file0.zip file0.txt
zip -r folder1.zip folder1
zip -r folder2.zip folder2
zip -r data.zip *.zip
#delete original data
rm -rf file* folder*

推荐阅读