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...

m4D_guY
  • 3
  • 1
  • 4
  • Note: quote properly, `-name "*.tar.gz"`. Compare [`find` utility does not output all files when using wildcards](https://superuser.com/q/1217773/432690). You may get away few times but it will hit you eventually. – Kamil Maciorowski Nov 27 '18 at 15:38

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).

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
  • Thanks, it worked. What does POSIX mean? – m4D_guY Nov 28 '18 at 20:25
  • @m4D_guY [Portable Operating System Interface](https://en.wikipedia.org/wiki/POSIX). A solution that is fully POSIX-compliant will work on variety of systems. In general there are many tools (or options) only supported on "large" Linuxes. If you can use them, great! But if you work with an embedded "minimal" Unix, or on Mac (where tools often differ from these of Linux) etc. then a solution that doesn't go beyond POSIX may be a lifesaver. – Kamil Maciorowski Nov 28 '18 at 20:41
  • To be honest i dont know how this works... i always only click the up button not the "check" button, where is the difference, a link is totally fine – m4D_guY Dec 03 '18 at 19:38
  • @m4D_guY Please take our [tour] then. You need 15 reputation to vote up; there is no such restriction for accepting an answer to any of your questions. If you got a good answer to your other question (not necessarily on Super User, Stack Overflow maybe?), consider accepting it as well. – Kamil Maciorowski Dec 03 '18 at 19:48
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
  • 9,782
  • 4
  • 20
  • 31