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.

4
  • 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.... Commented 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. Commented Aug 12, 2022 at 15:43
  • Also what to do if uzipping the file create more than one directory? Commented Aug 12, 2022 at 15:46
  • @Shortytot, have you consider not to extract all the files but first get list of files in zip and unzip them one by one to STDOUT and do your analysis? Commented Aug 12, 2022 at 16:02

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. Commented 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. Commented Aug 12, 2022 at 15:58
  • @Shortytot yes, if the commands will be run as part of the same script that's fine. Commented Aug 12, 2022 at 15:59
  • @Shortytot, please add this clarification in to the question: unix.stackexchange.com/posts/713434/edit Commented Aug 12, 2022 at 15:59
  • 1
    @RomeoNinov Sounds good. Thanks for reminding me! Commented Aug 12, 2022 at 16:01

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.