gunzip a file to a different location based on filename

Discussion in 'Command Line' started by Rob, Aug 28, 2013.

  1. Rob

    Rob Administrator Staff Member

    Messages:
    573
    Likes Received:
    185
    Trophy Points:
    43
    Hey guys,

    I have come across a backup script that stores multiple system files like this:

    _path_to_file.txt.gz
    _path_to_another_file.conf.gz

    Where the underscores form the directory structure.. so the two above would be:
    /path/to/file.txt
    /path/to/another/file.conf

    These are all in the /backup directory..
    Code:
    root@server [~]# ls /backup/
    _path_to_another_file.conf.gz  _path_to_file.txt.gz
    I want to write a script that will extract each file and put them where they want to be..

    so that _path_to_another_file.conf.gz extracts to /path/to/another/file.conf (and overwrites the current one)
    and that _path_to_file.txt.gz extracts to /path/to/file.txt (and overwrites the current one)

    I know I can tell gunzip to extract it anywhere.. like:
    Code:
    gunzip _path_to_file.txt.gz -c > /path/to/file.txt
    What I need is to run one command that will take each gz file, and extract it to its correct location by changing _ to / to find the path..


    Whatcha think?
  2. ryanvade

    ryanvade Administrator Staff Member Staff Writer

    Messages:
    1,161
    Likes Received:
    392
    Trophy Points:
    83
    Okay, to better understand... Lets say there is a
    /backup/_home_ryanvade_.config.gz
    and you want to gunzip, and overwrite the current
    /home/ryanvade/.config
    ?
    So you need a script to read the _ and replace with / for use as the gunziped location...
  3. Rob

    Rob Administrator Staff Member

    Messages:
    573
    Likes Received:
    185
    Trophy Points:
    43
    Correct..

    Also - the -c flag cats the file - so redirecting its output to the real file is nice because it won't change ownership, etc.. (so - basically the same as zcat.. which I may use instead)

    Also, there will never be files with actual underscores in the names..
  4. ryanvade

    ryanvade Administrator Staff Member Staff Writer

    Messages:
    1,161
    Likes Received:
    392
    Trophy Points:
    83
    Now that I think about it... it would be easiest to read the contents of the /backup directory, place in a CSV file, and then replace the _ to / in the file, and then use the file as the output variables to gunzip.
  5. Rob

    Rob Administrator Staff Member

    Messages:
    573
    Likes Received:
    185
    Trophy Points:
    43
    Yeah, i'll go that route..
  6. ryanvade

    ryanvade Administrator Staff Member Staff Writer

    Messages:
    1,161
    Likes Received:
    392
    Trophy Points:
    83
    So, maybe this will help:
    ls /build/backup
    _build_cogbuntu-12.04.tar.gz _build_test.tar.gz
    (Just to show what is in the folder )
    Now,
    Code:
     find /build/backup -maxdepth 3 -type f -iname "*" -printf "%f\n" > ~/list.csv && sed -i 's/_/\//g' ~/list.csv && less ~/list.csv
    gives:

    /build/cogbuntu-12.04.tar.gz
    /build/test.tar.gz

    instead of
    _build_cogbuntu-12.04.tar.gz
    _build_test.tar.gz
  7. Rob

    Rob Administrator Staff Member

    Messages:
    573
    Likes Received:
    185
    Trophy Points:
    43
    Yeah.. so far I came up with similar:
    Code:
    ls /backup/ |grep .gz > /backup/backup_files && sed -i 's,_,\/,g' /backup/backup_files && cat /backup/backup_files
  8. ryanvade

    ryanvade Administrator Staff Member Staff Writer

    Messages:
    1,161
    Likes Received:
    392
    Trophy Points:
    83
    I am not sure where to go from here but...
    #!/bin/bash
    echo " step one, make sure the files exist. "
    backupDirectory="/build/backup"
    if [ ! -d "$backupDirectory" ]; then
    echo "Backup directory does not exist. Exiting" && exit 1
    fi
    echo "Moving to backup directory"
    cd /build/backup

    function makeVariables {
    # Load text file lines into a bash array.
    OLD_IFS=$IFS
    IFS=$'\n'
    let line_counter=0
    for line in $(cat "/home/ryanvade/list.csv"); do
    let line_counter=$(($line_counter+1))
    printf "${line_counter}: ${line}\n"
    done
    IFS=$OLD_IFS
    files=()
    while read $OLD_IFS; do
    files+=("$REPLY")
    echo $REPLY
    done

    for files in "${files[@]}"; do echo "$files"; done
    }
    function readfile {
    echo "Okay, will continue"
    find /build/backup -maxdepth 3 -type f -iname "*" -printf "%f\n" > ~/list.csv && sed -i 's/_/\//g' ~/list.csv

    makeVariables;
    }

    echo "Do you wish to continue? "

    read -p "Continue (y/n)?" choice
    case "$choice" in
    y|Y ) readfile;;
    n|N ) echo "no"; exit;;
    * ) echo "invalid";;
    esac
    Rob likes this.
  9. Rob

    Rob Administrator Staff Member

    Messages:
    573
    Likes Received:
    185
    Trophy Points:
    43
    Yeah - you lost me there.. i'm not as proficient as you are it seems :)
  10. ryanvade

    ryanvade Administrator Staff Member Staff Writer

    Messages:
    1,161
    Likes Received:
    392
    Trophy Points:
    83
    okay...much simpler
    #!/bin/bash
    echo " step one, make sure the files exist. "
    backupDirectory="/build/backup"
    if [ ! -d "$backupDirectory" ]; then
    echo "Backup directory does not exist. Exiting" && exit 1
    fi
    echo "Moving to backup directory"
    cd /build/backup

    function makeVariables {
    echo "in make Variables"
    file='/home/ryanvade/list.csv'
    exec 4<$file

    while read -u4 t ; do
    echo $t
    echo "next"
    done
    }
    function readfile {
    echo "Okay, will continue"
    find /build/backup -maxdepth 3 -type f -iname "*" -printf "%f\n" > ~/list.csv && sed -i 's/_/\//g' ~/list.csv

    makeVariables
    }

    echo "Do you wish to continue? "

    read -p "Continue (y/n)?" choice
    case "$choice" in
    y|Y ) readfile;;
    n|N ) echo "no"; exit;;
    * ) echo "invalid";;
    esac

    Gives output:
    step one, make sure the files exist.
    Moving to backup directory
    Do you wish to continue?
    Continue (y/n)?y
    Okay, will continue
    in make Variables
    /build/cogbuntu-12.04.tar.gz
    next
    /build/test.tar.gz
    next

    So, in the makeVariables function is where we need to first off get a list of the actual file names and then use line A from the actual file names and then use line A from the lines.csv (directory locations) and combine them in a gunzip command..
  11. Rob

    Rob Administrator Staff Member

    Messages:
    573
    Likes Received:
    185
    Trophy Points:
    43
  12. ryanvade

    ryanvade Administrator Staff Member Staff Writer

    Messages:
    1,161
    Likes Received:
    392
    Trophy Points:
    83
    Rob likes this.
  13. Rob

    Rob Administrator Staff Member

    Messages:
    573
    Likes Received:
    185
    Trophy Points:
    43
    lol
    ryanvade likes this.
  14. ryanvade

    ryanvade Administrator Staff Member Staff Writer

    Messages:
    1,161
    Likes Received:
    392
    Trophy Points:
    83
    Yeah, you should at least add some error control. Maybe ask for permission before continuing... etc.

Share This Page