在不同的子目录中提取 .tar.gz 文件

在不同的子目录中提取 .tar.gz 文件

我有不同树种的物候数据,但它们被更大的Treegroup保存了。

的输出find . -name *.tar.gz是:

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

我想要提取其子目录中的每个文件,并且输出目录的名称应该与 tar 文件相同。

我设法用提取所有文件find . -name *.tar.gz -execdir tar -xvzf "{}" \;,但这并没有在压缩文件后创建目录名。

我该怎么做?-C需要目录已经存在...

所以最后我想

Tilia/EP725_DE_129_070/content_of_PEP725_DE_129_070.tar.gz

等等...

答案1

如果您的tar支持--one-top-level选项:

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

man 1 tar

--one-top-level[=DIR]

将所有文件提取到 中DIR,或者,如果不使用参数,则提取到由档案基本名称命名的子目录中(减去 可识别的标准压缩后缀--auto-compress)。

注:{}可能被引用,也可能不被引用,但*.tar.gz 应该引用以避免发生此类事故:find使用通配符时实用程序不会输出所有文件


如果你tar不支持--one-top-level选项,那么这-C是一个好主意,你只需要先创建一个相应的目录。但是,此命令更进一步,甚至不使用-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 {} \;

这里唯一的非 POSIX 组件是......它本身tartar仅被认可为遗留工具不支持 gzip。在 POSIX(自 2001 年起)中,tar相当于pax程序,同样不支持 gzip。据我所知,POSIX 中没有gzip(也没有等效的)支持,因此不可能创建完全符合正式 POSIX 标准的解决方案。

幸运gzip的是事实上标准。最坏的情况下,上述代码应该在(或)gzip之前运行。tarpax

答案2

就像是:

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 

未经测试,使用风险自负。

将以上内容复制到一个文件并将source该文件。

如果您喜欢冒险,您也可以将其变成一句话。

相关内容