распаковать в каталог с таким же базовым именем?

18

У меня есть файл в архиве, как myArchive123.tar.gz. Внутри находится папкаhelloWorld

Если я извлекаю это: tar -xf myArchive123.tar.gzя получаю helloWorldпапку:

ls 
myArchive123.tar.gz
helloWorld 

Я хотел бы, чтобы выходные данные имели то же имя, что и имя файла, за исключением расширения .tar.gz. То есть:

tar <magic paramaters> myArchive123.tar.gz 
ls 
 myArchive123.tar.gz
 myArchive123
cd myArchive123
ls 
  helloWorld

Можно ли это сделать?

  • Я никогда не знаю, что внутри архива. Может быть папкой, может быть много файлов.
  • Я мог бы использовать другой инструмент, если tar не может этого сделать.
  • Я был бы в порядке с более длинной формой, которую можно превратить в скрипт

РЕДАКТИРОВАТЬ
В то же время я взломал себе сценарий, который, кажется, выполняет свою работу. (см. мой опубликованный ответ ниже). Если это может быть улучшено, пожалуйста, не стесняйтесь оставлять комментарии / дополнительные ответы. Главное, чтобы он был упакован в одну строку вроде:

extract <file>
Лев Уфимцев
источник
1
Архив всегда содержит ровно одну папку?
Марк Плотник
Я не знаю, что внутри него во время экстракции. Это также не должно зависеть от того, что находится внутри архива. Если это папка, распакуйте ее там. если это файл, распакуйте все файлы.
Лев Уфимцев
В то же время я собрал сценарий (см. Ниже). Я могу принять ответ только через 2 дня.
Лев Уфимцев
Будет ли в архиве более одной папки на верхнем уровне?
Марк Плотник,

Ответы:

10

С помощью gnu tarвы можете использовать --xform(или --transform) для добавления /prefix/к каждому имени файла:

tar -xf myArchive.tar.gz --xform='s|^|myArchive/|S'

Обратите внимание , там нет ведущей /в prefix/и sedвыражении концов с , Sчтобы исключить символические цели ссылки из преобразований имен файлов.
Чтобы проверить это (всухую):

tar -tf myArchive.tar.gz --xform='s|^|myArchive/|S' --verbose --show-transformed-names

Для начала, вот очень упрощенный скрипт, который вы можете использовать как extract <file>:

STRIP = $ {1%. *} # Последний суффикс строки
ИМЯ = $ {ПОЛОСЫ% .tar} #strip .tar суффикс, если он присутствует
tar -xf "$ 1" --xform = "s | ^ | $ NAME / | S" #run
don_crissti
источник
Это близко к тому, что я хочу, за исключением того, что я хотел бы иметь возможность упаковать его во что-то вроде: extract <file>
Leo Ufimtsev
Это глючит, останавливается на первой точке. Например, у меня есть такой файл: eclipse-SDK-4.5M6-linux-gtk-x86_64.tar.gz Я ожидаю вывода без .tar.gz, но получаю eclipse-sdk-4
Лев Уфимцев,
В приведенном выше сценарии я удаляю расширение и удаляю его дальше, если найду «tar».
Лев Уфимцев
В общем, со многими типами архивов. Я надеялся на быструю однострочность, подумал, может быть, мне не хватало флага аргумента. Но кажется, что нет тривиального решения этого?
Лев Уфимцев
Хорошая вещь. Это работает и короче, чем сценарий, который я написал. Ницца!
Лев Уфимцев
7

Ну, вы можете сделать это, по крайней мере, за пару шагов. Если вы сделали

mkdir <archive name>
tar -xf <archive name>.tar.gz --strip-components=1 -C <archive name>

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

Эрик Ренуф
источник
3

редактировать

Принятый ответ короче, чем ниже. (сделать то же самое, но обычно лучше чем короче).


В конце концов я взломал сценарий для выполнения поставленной задачи. это работает с .tar .tar.gz и .gz

#!/bin/sh
#usage:
# nameOfScript myArchive.tar.gz
# nameOfScript myArchive.gz
# nameOfScript myArchive.tar
#
# Result:
# myArchive   //folder
fileName="${1%.*}" #extracted filename

#handle the case of archive.tar.gz
trailingExtension="${fileName##*.}"
if [ "$trailingExtension" == "tar" ]  
then
    fileName="${fileName%.*}"  #remove trailing  tar.
fi

mkdir "$fileName"
tar -xf "$1" --strip-components=0 -C "$fileName"

Использование:

   nameOfScript archive.tar.gz 
   ls 
    archive
   cd archive 
   ls 
    <archive content>

Обратите внимание, что это решение может содержать точки в имени файла. Например, Eclipse-4.5M-SDK.tar.gz.

Я держу скрипт в моем git-репо. Последнюю версию см. На странице https://github.com/LeoUfimtsev/ldts/blob/master/pathscripts/leo-tar-here.

Лев Уфимцев
источник
2

Еще одним возможным решением является использование --transformопции:

tar -xzf ARCHIVE_NAME.tgz --transform="s/OLD_DIR_NAME/ARCHIVE_NAME/"

С вашими файлами:

tar -xzf myArchive123.tar.gz --transform="s/helloWorld/myArchive123/"
SVQ
источник
1
но это предполагает, что вы знаете, что находится внутри архива
Лев Уфимцев
например, как бы я превратил это в однострочный скрипт, не зная, что внутри архива?
Лев Уфимцев
Ты прав. Это только одно возможное решение, как я написал здесь ...
svq
есть ли разница между этим и --strip-compoments = 0 myArchive123?
Лев Уфимцев
1
И --strip-components=0просто удаляет первое имя каталога из пути и с -Cопцией сохраняет деархивированные файлы в новый каталог.
SVQ