Bash script to select files to zip/unzip

6,590

You can use this for compression:

compress_file () 
{
    local dir file
    test -f "$1" || return 2
    dir="$(readlink -f "$1")"
    file="${dir##*/}"
    dir="${dir%/*}"
    cd "$dir"
    # check whether target file exists:
    # test -f "$file".zip && : whatever
    echo zip "$file".zip "$file"
}

compress_file /path/to/file

file selection for decompression

I am not familiar with zenity. It seems that it cannot filter files. You can approach the disired effect by creating a temporary directory, linking only the *.zip files into it and run zenity for this directory. Of course, if the user selects a different directory then he will see all files.

zipfile_dialog () 
{
    local file startdir="/home/ubuntu" tmpdirname=.zipscript.$$
    cd "$startdir" || return 2
    test -d "$tmpdirname" && { rm -r "$tmpdirname" || return 2; }
    mkdir -p "$tmpdirname" || return 2
    for file in *.zip; do
        cd "$tmpdirname"
        ln -s ../"$file"
        cd ..
    done
    ls "$tmpdirname"
    # call zenity here
    rm -r "$tmpdirname"
}

zipfile_dialog

An alternative approach would be to use the shell for file selection. That could be done with programmable completion if that is an option for you (complete, compgen).

Share:
6,590

Related videos on Youtube

Alex Andreadis
Author by

Alex Andreadis

Updated on September 18, 2022

Comments

  • Alex Andreadis
    Alex Andreadis over 1 year

    I'm trying to zip and unzip files with a bash script, but I'm new and I have problems. I will explain what the script currently does, and then what I wanted it to do.

    • User selects “compress”: a file dialog appears, showing all files. The user selects a file (e.g. /home/ubuntu/file.txt). The file is compressed and saved to /home/ubuntu as file.zip that contains /home/ubuntu/file.txt.

    • User selects “decompress”: a file dialog appears, showing all files. The user selects a file (e.g. /home/ubuntu/file.zip. The file is
      decompressed.

    Now what I want from the script to do:

    1. After compressing a file, I want the directory of that compressed file to be the same. For example, for /home/ubuntu/filename.txt, I want it to be saved in /home/ubuntu/ as filename.zip. I want it to contain only filename.txt inside and not /home/ubuntu/filename.txt or home/ubuntu/filename.txt.
    2. On decompression, I want the file dialog to show only *.zip files, so that the user could not select an file this is uncompressed.
    3. On decompression, I want to know where the file is saved.

    Here is my code:

    #! /bin/bash
    #This bash compresses and decompresses files
    act=-1 #A variable used to transfer which action has been  chosen
    action1="Compress"  
    action2="Decompress"  #action1 & 2 both used for certain echoes
    
    function menu { #The menu
        clear
        local title="-------Menu-------"
        local prompt="Please choose an action:"
        local options=("$action1" "$action2" "Quit")
    
        echo "$title"
        PS3="$prompt" #Changes the default '#?' that the select command uses to $prompt.
        select option in "${options[@]}";do
    
            case $option in
    
                ${options[0]})
                echo "You chose $option"
                act=0 #Changes act to 0 , to be used later      
                break   
                ;;
    
                ${options[1]})
                echo "You chose $option"
                act=1 #Changes act to 1 , to be used later              
                break;
                ;;
                ${options[2]}) 
                echo "You chose $option"
                exit
                ;;
                *)
                echo "Invalid option please choose between 1-3"
                ;;
            esac
            break
        done
    }
    
    function ynPrompt { #a y/n prompt to go back to the main menu or exit
        while true #helps to loop the y/n prompt in case of wrong input ex. a343
        do  
    
            read -r -p "Do you want to go back to the menu? [y/N] " response
            case $response in
    
                 [yY][eE][sS]|[yY]) #accepts yes or y and ignores casing ex. yEs is accepted.
                 continue 2     #continues the outer control loop
                 ;;
                 [nN][oO]|[nN])     #accepts no or n and ignores casing ex. nO is accepted.     
                 exit           #exits the script   
                 ;;
                 *)
                 continue           #shows the message again
                ;;      
            esac
            break
        done
    }
    
    function main { #Performs the selected action
        if [ $act -eq 0 ]; then
    
            if zip -r ${path}.zip ${path}   
            then echo Compression successful
            echo $? #prints 0 
            else echo $? 
            fi
    
    
            #echo "$action1"
            #zip -r ${path}.zip ${path}
    
        elif [ $act -eq 1 ]; then
    
            if unzip ${path} 
            then echo Decompression successful
            echo ${path}
            echo $? #prints 0
            else echo $?
            fi
    
            #echo "$action2"
            #unzip ${path}
    
    
        else 
            echo "$error"
        fi
    
    }
    
    
    
    #~~~~~~~~~~~~ Script start ~~~~~~~~~~~~~~~~
    while true #outer control loop
        do
        menu #call menu
        cd /home
        path=$(zenity --file-selection) #Stores the path of the file into path variable through zenity dialog 
    #path can only be .zip if i had --file filter *.zip
    
        if [ -z $path ]; then  #checks length of $path , returns true if length = 0 
            ynPrompt #call ynprompt
        else
            main     #call main
        fi
    
        break
    done
    
    • Hauke Laging
      Hauke Laging over 8 years
      You should describe your problem / question more precisely. It seems to me that your code is not relevant for the task you have described.
  • Alex Andreadis
    Alex Andreadis over 8 years
    can you add some comments on the code?
  • Hauke Laging
    Hauke Laging over 8 years
    @AlexAndreadis What don't you understand? Seems very simple to me.
  • Alex Andreadis
    Alex Andreadis over 8 years
    where to use them on my code?? I cant understand.