-1

I created a script to exact all tar.gz file it is composed of 5 tar files and the last tar file should remain tar it should not be extracted. So my problem is it will all extract the tar.gz file.

while true; do
    for f in *.tar.gz; do
        case $f in '*.tar.gz') exit 0;; esac
        tar zxf "$f"
        rm -v "$f"
    done
done

What is the correct way to my solve problem?

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
user3534255
  • 137
  • 1
  • 3
  • 14
  • It would be preferable if you edited [your original question](http://stackoverflow.com/questions/23507381/extract-file-using-bash-script) to clarify what you need done, instead of reposting the accepted answer here verbatim and elaborating on the objective. That would give @tripleee the chance to revise his code to properly address your problem. Instead we are left with two questions neither of which is particularly clear. – StvnW May 08 '14 at 12:35

2 Answers2

1

You say:

I created a script to exact all tar.gz file it is composed of 5 tar files and the last tar file should remain tar it should not be extracted.

I can see two interpretations for that:

  1. There are five files with the .tar.gz extension in a directory. The first four of those files should be extracted and removed; the fifth should be left unextracted.

  2. There is one .tar.gz file which contains 5 .tar files. The first four of those .tar files should be extracted from the .tar.gz; the fifth should be left unextracted.

There are many ways to deal with each scenario. I'm assuming that the tar file names do not contain spaces or newlines or other oddball characters (which is plausible). If you have oddball file names, it is probably simplest to sanitize them first. Amongst other things, these assumptions mean that you could safely use ls output. However, it is still best not to do so. I am going to assume that 5 is a fixed and magic number.

Scenario 1

i=0
for tarfile in *.tar.gz
do
    $(($i++))
    [ $i = 5 ] && break
    tar -xf "$tarfile"
done

This counts the files it extracts, and stops after the count reaches 5 (so it only extracts the first 4 files).

Scenario 2

tarfiles=$(tar -tf *.tar.gz | sed '$d')
tar -xf *.tar.gz $tarfiles

This collects the list of tar files contained inside the compressed tar file, and deletes the last one listed. It then requests tar to extract the remaining files — so the directory will contain the original .tar.gz file and all the files except the last extracted from the .tar.gz file. If the extracted files are tar files, you can then extract those individually:

for tarfile in $tarfiles
do tar -xf "$tarfile"
done

If you want to remove the extracted tar files too, you can do that.

Demo of Scenario 2

$ mkdir junk
$ cp *.c junk
$ cd junk
$ ls
bo.c     zigzag.c
$ for i in {1..5}; do tar -cf tarfile-$i.tar *.c; done
$ ls -l
total 144
-rw-r--r--  1 jleffler  staff    546 May  7 22:34 bo.c
-rw-r--r--  1 jleffler  staff  10752 May  7 22:35 tarfile-1.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-2.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-3.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-4.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-5.tar
-rw-r--r--  1 jleffler  staff   7305 May  7 22:34 zigzag.c
$ tar -czf tarfile-N.tar.gz *.tar
$ ls -l
total 152
-rw-r--r--  1 jleffler  staff    546 May  7 22:34 bo.c
-rw-r--r--  1 jleffler  staff  10752 May  7 22:35 tarfile-1.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-2.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-3.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-4.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-5.tar
-rw-r--r--  1 jleffler  staff   2787 May  7 22:36 tarfile-N.tar.gz
-rw-r--r--  1 jleffler  staff   7305 May  7 22:34 zigzag.c
$ tar -tvf tarfile-N.tar.gz
-rw-r--r--  0 jleffler staff   10752 May  7 22:35 tarfile-1.tar
-rw-r--r--  0 jleffler staff   10752 May  7 22:36 tarfile-2.tar
-rw-r--r--  0 jleffler staff   10752 May  7 22:36 tarfile-3.tar
-rw-r--r--  0 jleffler staff   10752 May  7 22:36 tarfile-4.tar
-rw-r--r--  0 jleffler staff   10752 May  7 22:36 tarfile-5.tar
$ rm *.tar *.c
$ ls -l
total 8
-rw-r--r--  1 jleffler  staff  2787 May  7 22:36 tarfile-N.tar.gz
$ tarfiles=$(tar -tf *.tar.gz | sed '$d')
$ echo $tarfiles
tarfile-1.tar tarfile-2.tar tarfile-3.tar tarfile-4.tar
$ tar -xf *.tar.gz $tarfiles
$ ls -l
total 104
-rw-r--r--  1 jleffler  staff  10752 May  7 22:35 tarfile-1.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-2.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-3.tar
-rw-r--r--  1 jleffler  staff  10752 May  7 22:36 tarfile-4.tar
-rw-r--r--  1 jleffler  staff   2787 May  7 22:36 tarfile-N.tar.gz
$ for file in $tarfiles; do echo $file; tar -tvf $file; rm $file; done
tarfile-1.tar
-rw-r--r--  0 jleffler staff     546 May  7 22:34 bo.c
-rw-r--r--  0 jleffler staff    7305 May  7 22:34 zigzag.c
tarfile-2.tar
-rw-r--r--  0 jleffler staff     546 May  7 22:34 bo.c
-rw-r--r--  0 jleffler staff    7305 May  7 22:34 zigzag.c
tarfile-3.tar
-rw-r--r--  0 jleffler staff     546 May  7 22:34 bo.c
-rw-r--r--  0 jleffler staff    7305 May  7 22:34 zigzag.c
tarfile-4.tar
-rw-r--r--  0 jleffler staff     546 May  7 22:34 bo.c
-rw-r--r--  0 jleffler staff    7305 May  7 22:34 zigzag.c
$ rm -f *
$ cd ..
$ rmdir junk
$
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • sorry for this, but the given code above is not working well, instead that it will extract 4 times the thing that it will do is to extract just once. so anyone can check this out ? – user3534255 May 15 '14 at 02:59
  • I can't help you more until you update the question with a more precise statement of the problem you are seeking to solve. I had to take a couple of guesses at what you might want, and if neither is doing what you need then you have to state more precisely what it is that you want — or illustrate more clearly what you've got in the way of files, or the contents of the tar files, or any more information to explain what you are seeking to do. – Jonathan Leffler May 15 '14 at 03:47
0

The problem is you are using this command to extract the file:

tar zxf "$f"

And what that does is decompress the gzip file & then extract tar the archive all at once. So all tarred contents would be extracted. Instead, what you want to do is use gzip -d instead:

gzip -d "$f"

That will only decompress the gzip. As for the logic of only extracting the contents of the first four tar archives but not the fifth, it seems like there is more code logic you are not sharing?

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103