ekstrak tar ke direktori dengan nama dasar yang sama?

18

Saya memiliki file zip seperti myArchive123.tar.gz. Di dalamnya berisi folder sepertihelloWorld

Jika saya mengekstraknya: tar -xf myArchive123.tar.gzSaya mendapatkan helloWorldfolder:

ls 
myArchive123.tar.gz
helloWorld 

Saya ingin output menjadi nama yang sama dengan nama file dikurangi ekstensi .tar.gz. Yaitu:

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

Bisakah ini dilakukan?

  • Saya tidak pernah tahu apa yang ada di dalam arsip. Bisa jadi folder, bisa banyak file.
  • Saya akan baik-baik saja dengan menggunakan alat lain jika tar tidak bisa melakukannya.
  • Saya akan baik-baik saja dengan bentuk yang lebih panjang yang dapat diubah menjadi skrip

EDIT
Sementara itu saya meretas sendiri skrip yang tampaknya menyelesaikan pekerjaan. (lihat jawaban saya di bawah). Jika dapat ditingkatkan, jangan ragu untuk mengirim komentar / jawaban tambahan. Hal utama adalah bahwa itu harus dikemas menjadi satu-liner seperti:

extract <file>
Leo Ufimtsev
sumber
1
Apakah arsip selalu mengandung tepat satu folder?
Mark Plotnick
Saya tidak tahu apa yang ada di dalamnya pada waktu ekstraksi. Ini seharusnya tidak bergantung pada apa yang ada di dalam arsip juga. Jika itu folder, ekstrak folder di sana. jika itu file, ekstrak semua file.
Leo Ufimtsev
Sementara itu saya mengumpulkan skrip (lihat di bawah). Saya hanya dapat menerima jawabannya dalam 2 hari.
Leo Ufimtsev
Apakah arsip akan pernah berisi lebih dari satu folder di tingkat atas?
Mark Plotnick

Jawaban:

10

Dengan gnu tar, Anda dapat menggunakan --xform(atau --transform) untuk menambahkan /prefix/ke setiap nama file:

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

catatan ada yang tidak terkemuka /di prefix/dan sedekspresi berakhir dengan Smengecualikan target symbolic link dari transformasi nama file.
Untuk mengujinya (dry-run):

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

Untuk membantu Anda memulai, berikut ini skrip yang sangat sederhana yang dapat Anda panggil sebagai extract <file>:

STRIP = $ {1%. *} #Strip akhiran terakhir
NAME = $ {STRIP% .tar} #strip .tar suffix, jika ada
tar -xf "$ 1" --xform = "s | ^ | $ NAME / | S" perintah #run
don_crissti
sumber
Ini dekat dengan yang saya inginkan, dengan pengecualian bahwa saya ingin dapat mengemasnya menjadi seperti: extract <file>
Leo Ufimtsev
Ini buggy, berhenti di titik pertama. Misalnya saya punya file seperti ini: eclipse-SDK-4.5M6-linux-gtk-x86_64.tar.gz Saya mengharapkan output tanpa .tar.gz, tapi saya mendapatkan eclipse-sdk-4
Leo Ufimtsev
Dalam skrip di atas saya strip ekstensi dan strip lebih jauh jika saya menemukan 'tar'.
Leo Ufimtsev
Secara umum, dengan banyak jenis arsip. Saya berharap untuk satu kalimat cepat, saya pikir mungkin saya kehilangan beberapa bendera argumen. Tapi sepertinya tidak ada solusi sepele untuk ini?
Leo Ufimtsev
Barang bagus. Ini berfungsi dan lebih pendek dari skrip yang saya tulis. Bagus!
Leo Ufimtsev
7

Ya, setidaknya Anda bisa melakukannya dalam beberapa langkah. Jika Anda melakukannya

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

itu akan menyelesaikan tugas, meskipun mungkin ada jawaban yang lebih kompak di luar sana.

Eric Renouf
sumber
3

Edit

Jawaban yang diterima lebih pendek daripada yang di bawah ini. (lakukan hal yang sama, tetapi lebih pendek biasanya lebih baik).


Saya akhirnya meretas naskah untuk tugas yang ada. ini bekerja dengan .tar .tar.gz dan .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"

Pemakaian:

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

Catatan, solusi ini mampu membuat titik dalam nama file. Misalnya Eclipse-4.5M-SDK.tar.gz.

Saya menyimpan script di repo git saya. Untuk versi terbaru, lihat: https://github.com/LeoUfimtsev/ldts/blob/master/pathscripts/leo-tar-here

Leo Ufimtsev
sumber
2

Satu lagi solusi yang mungkin adalah menggunakan --transformopsi:

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

Dengan file Anda:

tar -xzf myArchive123.tar.gz --transform="s/helloWorld/myArchive123/"
svq
sumber
1
tetapi ini mengandaikan bahwa Anda tahu apa yang ada di dalam arsip
Leo Ufimtsev
mis. bagaimana saya mengubahnya menjadi skrip satu baris tanpa mengetahui apa yang ada di dalam arsip?
Leo Ufimtsev
Kamu benar. Itu hanya satu solusi yang mungkin seperti yang saya tulis di sini ...
svq
apakah ada perbedaan antara itu dan --strip-compoments = 0 myArchive123?
Leo Ufimtsev
1
Dan --strip-components=0cukup menghapus nama direktori pertama dari path dan dengan -Copsi menyimpan file yang sudah diarsipkan ke direktori baru.
svq