How to jump the unpack directory in shell script? - linux

I want to unpack a .tgz file and jump to the directory released. I know the command in terminal is:
tar -xvzf xxx.tgz
and then jump to the direcotory:
cd xxx
But how can I do this in shell script? I don't know how to get the directory the 'tar' command released, can anyone help me?

As mentioned here:
test1=$(tar -axvf something-1.3.5a.tar.gz)
cd $(echo $test1 | cut -f1 -d" ")

The following would unarchive xxx.tgz and cd into whichever directory it extracts into:
tar -xvzf xxx.tgz && cd $(tar -tf ${_} | head -1 | cut -d / -f 1)
This takes that into account that the directory which the archive is extracted to might not be the same name as the archive. The method extracts the archive then checks it's contents in order to determine where it actually extracts to. There is some level of fragility to be aware of and adjustments might need to take place for unusual filenames.
Here are a couple of other (slightly more generic) examples:
mkdir -p xxx && tar -xvzf ${_}.tgz -C ${_%%.tgz}
Would create the directory xxx and extract xxx.tgz in xxx even if it normally extracts to xyz.
tar -xvzf xxx.tgz && cd ${_%%.tgz}
Unarchives xxx.tgz then uses bash parameter substitution to cd into the xxx directory.

Related

I am working in linux and have tot extract archives that were already in an archive. Could anyone explain how to extract this while using loops?

#!/bin/bash
tar -xvf assignment_UA_InleidingProgrammeren_Huistaak1-HelloWorld_2019-11-11.tgz
a=$(echo assignment_UA_InleidingProgrammeren_Huistaak1-HelloWorld_2019-11-11.tgz | cut -b 15-35)
b=$(echo assignment_UA_InleidingProgrammeren_Huistaak1-HelloWorld_2019-11-11.tgz | cut -b 37-56)
#cutcommand van geeksforgeeks.org
mkdir -p "$a"/"$b"
mv assignment_UA_InleidingProgrammeren_Huistaak1-HelloWorld_2019-11-11/*.tgz InleidingProgrammeren/Huistaak1-HelloWorld
rmdir assignment_UA_InleidingProgrammeren_Huistaak1-HelloWorld_2019-11-11
for x in InleidingProgrammeren/Huistaak1-HelloWorld
I have already extracted the first archive but i have to extract tthe tgz archives that are in this archive without using hardcode.
I have tried using different loops but it doesn't work and i don't know if i am using them correctly.
Assumptions:
you have an archive, a.tgz, containing some files.
you have an archive, b.tgz, containing some files.
both a.tgz and b.tgz are themselves contained in another archive, top.tgz.
both a.tgz and b.tgz do not exist outside top.tgz when the script starts.
t.tgz
    - a.tgz
         - some files
    - b.tgz
         - some files
Script:
#!/bin/bash
tar -xzf top.tgz
rm -f top.tgz
for F in *.tgz
do
tar -xzf "$F"
rm -f "$F"
done
Extract the top archive first.
Delete that top archive (or move it somewhere else) so the for F in *.tgz does not process it again.
Then loop on the new archives and extract them.
Final result, all files from a.tgz and b.tgz are available.

Is this possible in this command to cd into the directory thats printed in output

When I do ls | grep -e *-folder1 it prints my-folder1 that's the name of the folder matched in the command in current directory.
Is there a way I can add something like cd into this directory. This is more of an attempt to learn Bash or commands on Linux, rather than about doing what I am trying to accomplish.
You could do
ls | grep -- -folder1 | while read -r dir
do
cd "$dir"
# do things in $dir
done
# do things in the original directory
but parsing the output of ls is not recommended. You could instead use globbing:
for dir in *-efolder*
do
cd "$dir"
# do things in $dir
cd .. # need to back out again
done
# do things in the original directory
If the purpose isn't to grep on all folders matching a certain pattern and to cd down into each one of them, but to simply cd into a directory ending with -folder1, then:
cd *-folder1
If you get zero or multiple hits, cd will shown an error.

linux shell tar unwanted extra directories

I have the following problem:
I have directorties a/b/c and inside c many text files.
I want to make a .tar.gz file in drectory a/mydir with the c directory inside and then unzip it to that same directory to create a/mydir/c (with all the files inside)
I am at directory a and run: (shell)
~:$ tar -czf mydir/output.tar.gz b/c
~:$ tar -zxf mydir/output.tar.gz -c mydir
but the result is directories a/mydir/b/c (with the files inside)
The problem is I don't want directory b in the middle, just c with all its contents
This works for me. Create data
mkdir -p a/b/c
echo 42 > a/b/c/file.dat
Archive
tar zc -f c.tar.gz -C a/b c
created a/b/c directories, from directory a kindly try this command.
so the file under b/c/files were done out.tar.gz
new directory "mydir" create under "b" and files extracted too.
out.tar.gz removed from "a".
# tar -cvzf out.tar.gz b/c/* ; mkdir -p b/mydir ; tar -xvzf out.tar.gz -C b/mydir/ ; rm -rf out.tar.gz
Thanks!

How do I tar a directory without retaining the directory structure?

I'm working on a backup script and want to tar up a file directory:
tar czf ~/backup.tgz /home/username/drupal/sites/default/files
This tars it up, but when I untar the resulting file, it includes the full file structure: the files are in home/username/drupal/sites/default/files.
Is there a way to exclude the parent directories, so that the resulting tar just knows about the last directory (files)?
Use the --directory option:
tar czf ~/backup.tgz --directory=/home/username/drupal/sites/default files
Hi I've a better solution when enter in the specified directory it's impossible (Makefiles,etc)
tar -cjvf files.tar.bz2 -C directory/contents/to/be/compressed .
Do not forget the dot (.) at the end !!
cd /home/username/drupal/sites/default/files
tar czf ~/backup.tgz *
Create a tar archive
tar czf $sourcedir/$backup_dir.tar --directory=$sourcedir WEB-INF en
Un-tar files on a local machine
tar -xvf $deploydir/med365/$backup_dir.tar -C $deploydir/med365/
Upload to a server
scp -r -i $privatekey $sourcedir/$backup_dir.tar $server:$deploydir/med365/
echo "File uploaded.. deployment folders"
Un-tar on server
ssh -i $privatekey $server tar -xvf $deploydir/med365/$backup_dir.tar -C $deploydir/med365/
To gunzip all txt (*.txt) files from /home/myuser/workspace/zip_from/
to /home/myuser/workspace/zip_to/ without directory structure of source files use following command:
tar -P -cvzf /home/myuser/workspace/zip_to/mydoc.tar.gz --directory="/home/myuser/workspace/zip_from/" *.txt
If you want to tar files while keeping the structure but ignore it partially or completely when extracting, use the --strip-components argument when extracting.
In this case, where the full path is /home/username/drupal/sites/default/files, the following command would extract the tar.gz content without the full parent directory structure, keeping only the last directory of the path (e.g. files/file1).
tar -xzv --strip-components=5 -f backup.tgz
I've found this tip on https://www.baeldung.com/linux/tar-archive-without-directory-structure#5-using-the---strip-components-option.
To build on nbt's and MaikoID's solutions:
tar -czf destination.tar.gz -C source/directory $(ls source/directory)
This solution:
Includes all files and folders in the directory
Does not include any of the directory structure (or .) in the final product
Does not require you to change directories.
However, it requires the directory to be given twice, so it may be most useful in another script. It may also be less efficient if there are a lot of files/folders in source/directory. Adjust the subcommand as necessary.
So for instance for the following structure:
|- source
| |- one
| `- two
`- working
the following command:
working$ tar -czf destination.tar.gz -C ../source $(ls ../source)
will produce destination.tar.gz where both one and two (and sub-files/-folders) are the first items.
This worked for me:
gzip -dc "<your_file>.tgz" | tar x -C <location>
For me -C or --directory did not work, I use this
cd source/directory/or/file
tar -cvzf destination/packaged-app.tgz *.jar
# this will put your current directory to what it previously was
cd -
Kindly use the below command to generate tar file without directory structure
tar -C <directoryPath> -cvzf <Path of the tar.gz file> filename1 filename2... filename N
eg:
tar -C /home/project/files -cvzf /home/project/files/test.tar.gz text1.txt text2.txt
tar -Cczf ~/backup.tgz /home/username/drupal/sites/default/files
-C does the cd for you

uncompressing a large number of files on the fly

I have a script that I need to run on a large number of files with the extension **.tar.gz*.
Instead of uncompressing them and then running the script, I want to be able to uncompress them as I run the command and then work on the uncompressed folder, all with a single command.
I think a pipe is a good solution for this but i haven't used it before. How would I do this?
The -v orders tar to print filenames as it extracts each file:
tar -xzvf file.tar.gz | xargs -I {} -d\\n myscript "{}"
This way the script will contain commands to deal with a single file, passed as a parameter (thanks to xargs) to your script ($1 in the script context).
Edit: the -I {} -d\\n part will make it work with spaces in filenames.
The following three lines of bash...
for archive in *.tar.gz; do
tar zxvf "${archive}" 2>&1 | sed -e 's!x \([^/]*\)/.*!\1!' | sort -u | xargs some_script.sh
done
...will iterate over each gzipped tarball in the current directory, decompress it, grab the top-most directories of the decompressed contents and pass those as arguments to somescript.sh. This probably uses more pipes than you were expecting but seems to do what you are asking for.
N.B: tar xf can only take one file per invocation.
You can use a for loop:
for file in *.tar.gz; do tar -xf "$file"; your commands here; done
Or expanded:
for file in *.tar.gz; do
tar -xf "$file"
# your commands here
done

Resources