0

I'm trying to make a script where I can unzip a file and then cd into that unzipped file (ie. unzip test.zip and then cd into the test folder). The problem is that the name of the zip file varies and I'm trying to write a script that will work regardless of the name.

Currently, I have:

for file in $(ls *.zip);
do
        unzip ${file}
        cd ${file};
done

but I'm getting an error because ${file} is still a .zip file (if I understand the error correctly).

Any suggestions?

Thanks.

Edit:To clarify, I'm trying to do analysis on the files that are inside the .zip file. So I think my goal is to unzip the file first (which will then create a directory with the same name as the zip file without the .zip) and then cd into that directory. Once inside that directory, then I would have another line of code that would start the analysis of the files.

6
  • 2
    Please see mywiki.wooledge.org/ParsingLs for why you should never do for file in $(ls). In this case, it isn't even helping at all: it is shorter, easier and safer to do for file in *zip; do....
    – terdon
    Aug 12, 2022 at 15:40
  • 1
    FYI it is not required to have directory created from extract zip to have same name as zip. Aug 12, 2022 at 15:43
  • Also what to do if uzipping the file create more than one directory? Aug 12, 2022 at 15:46
  • @terdon Very informative. Thank you!
    – Shortytot
    Aug 12, 2022 at 15:48
  • 1
    @RomeoNinov Thanks for letting me know!
    – Shortytot
    Aug 12, 2022 at 15:49

1 Answer 1

1

Assuming that i) the zip file creates a new directory and ii) the name of that directory is the same as the name of the zip file without the .zip extension (note that both of these assumptions will very often be wrong), then you can do:

for file in *.zip
do
    unzip -- "$file"
    cd -- "${file%%zip}"
done

The ${file%%zip}, or more generally the syntax ${variable%%pattern} will return the value of $variable with pattern removed. So ${file%%zip} will return foo if the file's name is foo.zip.

The -- are there to signify the end of options, which can be useful if you can have file names starting with -. Also note how there is no need to use ls at all, which is a very good thing since parsing the output of ls is very fragile and never recommended.

You can make this a little bit more sophisticated by making sure the directory exists first:

for file in *.zip
do
    unzip -- "$file"
    [ -d "${file%%zip}" ] && cd -- "${file%%zip}"
done

Note that this is only useful if you now want to do things in the script that run in the directory. Otherwise, if you expect to run this and have your current shell session now be in the target dir, that won't happen because the cd don't affects the shell running the script which is not the shell you launched the script from.

So if you want this to be a way for you to extract the file, move to the new directory and then do things in an interactive shell session, you need to make this a function and not a script:

unzipcd(){
    for file in *.zip
    do
        unzip -- "$file"
        [ -d "${file%%zip}" ] && cd -- "${file%%zip}"
    done
}
5
  • 1
    @RomeoNinov there can only be one with the same name, so that doesn't really seem to be much of a limitation. If the zip file creates multiple directories, then at least this will move the OP into one of them if it has the right name.
    – terdon
    Aug 12, 2022 at 15:50
  • To clarify, I'm trying to do analysis on the files that are inside the .zip file. So I think my goal is to unzip the file first (which will then create a directory with the same name as the zip file without the .zip) and then cd into that directory. Once inside that directory, then I would have another line of code that would start the analysis of the files. Would that be possible? Sorry, I'm just starting out with linux command lines.
    – Shortytot
    Aug 12, 2022 at 15:58
  • @Shortytot yes, if the commands will be run as part of the same script that's fine.
    – terdon
    Aug 12, 2022 at 15:59
  • @Shortytot, please add this clarification in to the question: unix.stackexchange.com/posts/713434/edit Aug 12, 2022 at 15:59
  • 1
    @RomeoNinov Sounds good. Thanks for reminding me!
    – Shortytot
    Aug 12, 2022 at 16:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .