0

i have phenological data of different tree species, but they are saved by the bigger Treegroup.

The output of find . -name *.tar.gzis:

./Tilia/PEP725_DE_129_070.tar.gz
./Tilia/PEP725_DE_129_071.tar.gz
./Fagus/PEP725_DE_108_010.tar.gz
./Acer/PEP725_DE_115_000.tar.gz
./Acer/PEP725_DE_115_030.tar.gz
./Betula/PEP725_DE_106_020.tar.gz

I want to extract every file in their subdirectory and the name of the output directory should be the same as the tar-file.

I manage to extract all with find . -name *.tar.gz -execdir tar -xvzf "{}" \; But this does not create a directory name after the zipped files.

How do i do this? -C needs the directory already to be existend...

So in the end i would like to have

Tilia/EP725_DE_129_070/content_of_PEP725_DE_129_070.tar.gz

and so on...

2 Answers2

1

If your tar supports --one-top-level option:

find . -name "*.tar.gz" -execdir tar --one-top-level -xvzf {} \;

From man 1 tar:

--one-top-level[=DIR]

Extract all files into DIR, or, if used without argument, into a subdirectory named by the base name of the archive (minus standard compression suffixes recognizable by --auto-compress).

Note: {} may or may not be quoted but *.tar.gz should be quoted to avoid mishaps like this: find utility does not output all files when using wildcards.


If your tar doesn't support --one-top-level option then -C is quite a good idea, you just need to create a respective directory first. This command, however, goes a step further and doesn't even use -C:

find . -type f -name "*.tar.gz" -execdir sh -c '
   dirn="${1%.tar.gz}"         # desired directory name
   mkdir -- "$dirn"            # creating a directory
   cd -- "$dirn" &&
   tar -xvzf ../"$1"           # extracting to it
' find-sh {} \;

The only non-POSIX component here is… the tar itself. tar is only recognized as a legacy tool without gzip support. In POSIX (since 2001), the equivalent of tar is the pax program, also without gzip support. As far as I know there is no gzip (nor equivalent) in POSIX, so it's impossible to create a solution fully compliant with the formal POSIX standard.

Fortunately gzip is a de facto standard. In the worst case the above piece of code should run gzip before tar (or pax).

0

Something like:

for f in $(find . -name *.tar.gz); 
do 
    cd $(dirname $d)       # to ./Tilia/
    d=$(basename $f .tar.gz)  
    mkdir $d               # ./Tilia/PEP725_DE_129_070
    cd $d                  # To ./Tilia/PEP725_DE_129_070
    tar -xvzf ../$d.tar.gz # extracting ./Tilia/PEP725_DE_129_070.tar.gz in ./Tilia/PEP725_DE_129_070
    cd ../..               # back to top
done 

Untested, use at your own risk.

Copy above to a file and source the file.

If you feel adventurous, you can also make that a one-liner.

xenoid
  • 10,597