Unzip içindeki katranın “--strip-components = 1” ile eşdeğerdir?


48

Bir tar.gz dosyasını belirtilen alt dizine mysubfolder'a çıkaran bir betiğim var :

mkdir mysubfolder; tar --extract --file=sourcefile.tar.gz --strip-components=1 --directory=mysubfolder;

Bunu bir zip dosyasıyla yapmanın eşdeğer bir yolu var mı?


2
Sadece bsdtar kullanın
drizzt

Yanıtlar:


26

Mathias'in dediği unzipgibi, böyle bir seçeneğe sahip değil, ancak bir liner bash betiği işi yapabilir.

Sorun şudur: en iyi yaklaşım arşiv düzeninize bağlıdır. İçeriği doğrudan arşiv kökünde ise (üstünü sıyırıp sıyrılmanın ve kaosun kaosunu düşünün) tek bir üst düzey direk varsayan bir çözüm sefil bir şekilde başarısız olacaktır ./a/foo /b/foo /foo/a/b

Ve aynı başarısızlık da olur tar --strip-component. Tek bedene uyan tek bir çözüm yoktur.

Böylece, bir tane (ve sadece bir tane) olduğunu varsayarak, kök dizinini soymak için :

unzip -d "$dest" "$zip" && f=("$dest"/*) && mv "$dest"/*/* "$dest" && rmdir "${f[@]}"

İkinci seviye dosyaların / dizinlerin üst seviye üst öğenin adıyla aynı olmadığından emin olun (örneğin, /foo/foo). Ama /foo/bar/foove /foo/bar/bartamam. Eğer yaparlarsa veya sadece güvende olmak istiyorsan, çıkarma için geçici bir dir kullanabilirsin:

temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
mv "$temp"/*/* "$dest" && rmdir "$temp"/* "$temp"

Bash kullanıyorsanız, üst seviyenin tek bir dir olup olmadığını test edebilirsiniz:

f=("$temp"/*); (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] && echo "Single dir!"

Bash'den bahsederken, dotglobgizli dosyaları dahil etmek için açmalısınız ve her şeyi tek bir kullanışlı fonksiyona sarabilirsiniz:

unzip-strip() (
    local zip=$1
    local dest=${2:-.}
    local temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
    shopt -s dotglob && local f=("$temp"/*) &&
    if (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] ; then
        mv "$temp"/*/* "$dest"
    else
        mv "$temp"/* "$dest"
    fi && rmdir "$temp"/* "$temp"
)

Şimdi bunu kendinize koyun ~/.bashrcya da bir ~/.profiledaha asla endişelenmenize gerek kalmayacak. Basitçe kullanın:

unzip-strip sourcefile.zip mysubfolder

( mysubfolderyoksa sizin için otomatik olarak oluşturacağına dikkat edin )


Bu, umduğum gibi varolan bir dizin yapısını açmayacak (mysubfolder yerine. Kullanmaya çalıştım). Ben sadece unzipping (unzip zip-with-top-dir.zip) ve sonra kopyalama (cp -rv ekstresi-top-zip-dir / *.) İle bitirdim.
catgofire

4

Manuel sayfalardaunzip böyle bir seçenek bulamadım , korkarım bu imkansız. :(

Ancak, (duruma bağlı olarak) bunun etrafında çalışabilirsiniz. Örneğin, zip dosyasındaki tek üst düzey dizinin foo-ardından bir sürüm numarasıyla adlandırıldığından eminseniz, şöyle bir şey yapabilirsiniz:

cd /tmp
unzip /path/to/file.zip
cd foo-*
cp -r . /path/to/destination/folder

Güzel bir yaklaşım, ancak biraz eksik: tam çıkarılan içerikle hala foo * dir'iniz olacak.
MestreLion

Evet, rm -rf foo-*potansiyel olarak tehlikeli olduğundan bilerek eklemedim . Ya zaten adında bir klasör varsa foo-bar? Çıkartma işleminin /tmp, her seferinde ve sonrasında otomatik olarak boşaltılan klasör içerisinde yapıldığını unutmayın .
Mathias Bynens

Bu nedenle işlemleri zincirledim &&: verilen bir adım sadece önceki adım başarılı olursa gerçekleşir, yani son adım (ancak rm) yalnızca tüm adımlar hatasız bir şekilde tamamlanırsa çalışır .
MestreLion

2
İşte bu yüzden hiç kimse /tmp/some-hardcoded-folder-namegeçici klasör olarak kullanılmamalı, bunun yerine bunun kullanılmalı mktemp: böyle bir klasör bulunmayacağının garantisi. Aşağıdaki cevabımı kontrol et.
MestreLion

1

-jYolları önemsiz yapmak için kullanabilirsiniz (dizin oluşturmayın). Bu, yalnızca ortak tek seviyeli arşivler için önerilir. Çok seviyeli dizin yapılarına sahip arşivler düzleştirilecektir - bu, dosyaların çıkartılması için isim çakışmalarına bile yol açabilir.

Sıkıştırmayı aç sayfasındaki man sayfasından:

   -j     junk  paths.   The  archive's directory structure is not recreated; all files are deposited in the
          extraction directory (by default, the current one).
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.