У меня есть фенологические данные о разных породах деревьев, но они сохраняются большей группой деревьев.

Выход 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

и так далее...

2 ответа2

0

Если ваш 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-компонент здесь - это сам tar . tar распознается только как устаревший инструмент без поддержки gzip. В POSIX (с 2001 года) эквивалентом tar является программа pax , также без поддержки gzip. Насколько я знаю, в POSIX нет gzip (или его эквивалента), поэтому невозможно создать решение, полностью совместимое с формальным стандартом POSIX.

К счастью, gzip является стандартом де-факто . В худшем случае приведенный выше фрагмент кода должен запускать gzip перед tar (или pax).

0

Что-то вроде:

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 файла.

Если вы чувствуете себя авантюрным, вы также можете сделать это одной строкой.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .