1

I have many zip files (think 100-150) in a folder. Each zip file has multiple files with different file extensions. I know how to write a bash for loop to unzip all the contents of these files.

What I want to do is this.... Use 7z (or some other) to unzip each zip file and given the contents of that zip file the same file name as the zip file.

This is what I have currently.

#!/bin/bash
for i in *.zip;
    do
        echo $i #For debugging purpose
        7z x $i &
    done

Edit 2:

#!/bin/bash


for i in *.zip;
    do
        fbname=$(basename "$i" .zip);
        fem_fileName=$(unzip -l $i | grep .fem | awk '{print $4}')
        echo $fbname
        echo $fem_fileName
        $unzip $i
        7z e $i *.fem -y
        #echo $fbname
        #echo $fem_fileName
        mv $fem_fileName $fbname
    done

The newest issue is: what if the zip file I am operating on has multiple sub-directories? How do I have 7z or other utility recursively check for "folder in folder in zip file"?

Zip_file:

|----Folder_1

|------------Folder_2

|--------------------Contents_to_extract

Contents_to_extract > change file name to > zip_file

  • 1
    Do you want to rename the files as they are extracted from the zip file as the name of the zip file itself? – Terrance Dec 7 '17 at 0:24
  • @Terrance Yes. That is the case. excuse my english. I want all files in each zip file to be extracted and have the same name as the zip file itself. – drN Dec 7 '17 at 0:56
2

I don't think 7z has a way to rename files while extracting (like, say, tar does). You can, instead, extract to a folder, and rename everything in that folder to match the filename:

#! /bin/bash

for i in *.zip;
do
    echo $i # For debugging
    filename="${i%.*}"  # get filename without .zip
    (
        7z x -o"$filename" "$i"; # extract to directory named after zip file
         cd "$filename"
         shopt -s globstar
         for i in "$filename"/**; do
             # move everything in directory to parent folder with new name
             [[ -f $i ]] || continue # only files
             mv "${i}" ../"${filename}.${i##*.}"  # but keep extension
         done
         cd ..; rm -r "$filename" # cleanup
     )&
done
  • I'll try this out. Currently, I updated my Q with my nouvelle attempt. However, what if the zip file itself has multiple folders within? – drN Dec 7 '17 at 1:57
  • @drN Add an example zip file structure and what you want at the end of it to the question. – muru Dec 7 '17 at 1:58
  • added a complex file structure to my question. tjhanks. – drN Dec 7 '17 at 2:00
  • @drN "and what you want at the end of it" as well – muru Dec 7 '17 at 2:06
  • done to the best of my english. – drN Dec 7 '17 at 2:08
0

I found a solution. It was catalyzed by the small comment discussion I had with @muru.

Please read the comments carefully in the bash script below.

#!/bin/bash
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#Checks within each .zip file in current folder
#for the presence of a .xyz or .abc file
#
#When a .xyz or .abc file is found, it extracts the latest version of it into
# ./xyzfiles or ./abcfiles AND renames these extracted .xyz or .abc files with
#the same name as the original zip file.
#
#Note that the xyzfiles and the abcfiles folder SHOULD BE FIRST CREATED!!
#
# Author: Anon
# Ver 2.0 / 7-Dec-2017
#
#''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

for i in *.zip;
    do
        xyz_exists=$(zipinfo $i | grep "xyz" | wc -l)
        abc_exists=$(zipinfo $i | grep "abc" | wc -l)
        if [ $xyz_exists != 0 ]
            then 
                #echo true
                path_to_file=($(zipinfo $i | grep "xyz" | awk '{print $9}'))  
                #echo $path_to_file    
                new_name_0=$i
                #echo $new_name_0
                new_name=$(echo "${new_name_0%.*}")
                #echo $new_name
                unzip -o -qq $i #Unzip while overwriting (-o), al done very quietly (-qq)
                mv $path_to_file ./xyzfiles/$new_name
        elif [ $abc_exists != 0 ]
            then
                #echo true
                path_to_file=($(zipinfo $i | grep "abc" | awk '{print $9}'))  
                #echo $path_to_file    
                new_name_0=$i
                #echo $new_name_0
                new_name=$(echo "${new_name_0%.*}")
                #echo $new_name
                unzip -o -qq $i #Unzip while overwriting (-o), al done very quietly (-qq)
                mv $path_to_file ./abcfiles/$new_name
        fi
    done

For the moment, this works fine. There could be logical issues within the zip files being looked into... I have not encountered them YET.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.