Bir dizinin kendisini eklemeden dosya ve klasör dizinini nasıl tarlayabilirim?


382

Genellikle yaparım:

tar -czvf my_directory.tar.gz my_directory

Sadece her şeyi (herhangi bir gizli sistem dosyası dahil) dizinimde değil, dizinimde eklemek istersem ne olur? İstemiyorum:

my_directory
   --- my_file
   --- my_file
   --- my_file

İstiyorum:

my_file
my_file
my_file

Yapmanın varsayılan davranışı bu tar -czfmu? Benim durumumda sadece dosyaları saklıyor, dizini değil. Ben sadece tardizin içerir ama tar -czfonunla sadece dosyaları ekliyor.
Durga Swaroop

Yanıtlar:


233
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd - 

işi bir satırda yapmalı. Gizli dosyalar için de iyi çalışır. "*" gizli dosyaları en azından bash'ta yol adı genişletmesiyle genişletmez. Aşağıda benim denemem:

$ mkdir my_directory
$ touch my_directory/file1
$ touch my_directory/file2
$ touch my_directory/.hiddenfile1
$ touch my_directory/.hiddenfile2
$ cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
$ tar ztf my_dir.tgz
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2

2
Bu, boşluklu veya diğer özel karakterlere sahip dosyalar üzerinde de çalışır. Aferin!
PanCrit

29
Mükemmel değil - tar dosyası '.' İçeriyor ve sadece dosya1 yerine ./file1. Katranı kaldırırken --strip bileşenlerini kullanmak için aşağıdaki mateusza'nın çözümünü seviyorum.
Ivan

23
@Ivan komut .ile değiştirirseniz , *o cd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..zaman beklediğiniz gibi çalışacaktır.
İsimsiz

3
@jmathew Mevcut kabuğunuzun çalışma dizininin değişmemesi için alt kabuk da kullanabilirsiniz:$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
Alec

Bunun eski bir cevap olduğunu biliyorum ama cddizinlere girip çıkmak oldukça topal. En azından kullanmak olabilir pushdve popdeğer targibi bayrakları yoktu -C.
Andris

667

-CKatran anahtarını kullanın :

tar -czvf my_directory.tar.gz -C my_directory .

-C my_directoryİçin geçerli dizini değiştirmek için tar söyler my_directoryve sonra .(gizli dosyalar ve alt dizinleri dahil) "tüm geçerli dizin eklemek" anlamına gelir.

Bunu -C my_directoryyapmadan önce yaptığınızdan emin olun yoksa .dosyaları geçerli dizine alırsınız.


5
+1 teşekkür ederim! Kahretsin '.' Kayboldum. çok ağırlaştırıcı
JCotton

14
"Çoğu seçeneğin aksine, -C, işlenecek dosyalar listesinde gerçekleştiği noktada işlenir. Aşağıdaki komutu göz önünde bulundurun: tar --create --file=foo.tar -C /etc passwd hosts -C /lib libc.a" apl.jhu.edu/Misc/Unix-info/tar/tar_65.html Her zaman denerim tar -czvf my_directory.tar.gz * -C my_directoryve Bu çalışmıyor. -Ckonumu önemlidir! Kahretsin tar ...
m-ric

57
Mükemmel değil - tar dosyası '.' İçeriyor ve sadece dosya1 yerine ./file1. Katranı kaldırırken --strip bileşenlerini kullanmak için aşağıdaki mateusza'nın çözümünü seviyorum.
Ivan

3
@Superole: kabuk , katranı çalıştırmadan önce joker karakterlerin yerine geçer. Ayrıca, joker karakter kullanmanın *gizli dosyalar (orijinal gereksinim olan) içermeyeceğini unutmayın .
dubek

28
Yaratır. .tar.gz dosyasında bir kök dizin olarak.
İsimsiz

59

Ayrıca her zamanki gibi arşiv oluşturabilir ve aşağıdakilerle ayıklayabilirsiniz:

tar --strip-components 1 -xvf my_directory.tar.gz

3
Bu çözüm, özellikle tüm gereksinimleriniz bilinmeden önce oluşturulan tarballlarla çalıştığınız durumlarda iyidir ...
Digger

2
Bunun --strip-componentsbir GNU uzantısı olduğunu unutmayın.
zneak

2
Bu cevap, bağlamda "her zamanki gibi" örneği verilerek geliştirilebilir.
Josh Habdas

33

Göz at --transform/ ' --xformdosya arşive eklendiğinde olarak, bu size dosya adını masaj fırsatı verir:

% mkdir my_directory
% touch my_directory/file1
% touch my_directory/file2
% touch my_directory/.hiddenfile1
% touch my_directory/.hiddenfile2
% tar -v -c -f my_dir.tgz --xform='s,my_directory/,,' $(find my_directory -type f)
my_directory/file2
my_directory/.hiddenfile1
my_directory/.hiddenfile2
my_directory/file1
% tar -t -f my_dir.tgz 
file2
.hiddenfile1
.hiddenfile2
file1

Dönüşüm ifadesi ile benzerdir sedve /( ,yukarıdaki örnekte) dışında ayırıcılar kullanabiliriz .
https://www.gnu.org/software/tar/manual/html_section/tar_52.html


3
Bunu yapardım. Başka bir şey sadece bir kesmek!
jwg

2
Bu çok daha iyi bir çözüm.
leesei

Bu en iyi çözüm.
justhalf

1
İyi bir çözüm, ama neden olabilir file list too long. Benim çözümüm bunu önlüyor ve daha esnek.
17'de

Bu harika bir çözüm. Ayrıca --xformbirden çok yol için birden çok kez geçebilirsiniz .
elig

26

TL; DR

find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

Bazı durumlarda (yalnızca dosyaları, dizinleri ve sembolik bağlantıları arşivleyin):

find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

açıklama

Aşağıdaki maalesef ./arşivde bir üst dizin içeriyor :

tar -czf mydir.tgz -C /my/dir .

--transformYapılandırma seçeneğini kullanarak tüm dosyaları bu dizinin dışına taşıyabilirsiniz , ancak bu .dizinin kendisinden kurtulamaz . Komuta uymak gittikçe zorlaşıyor.

$(find ...)Komuta bir dosya listesi eklemek için kullanabilirsiniz ( magnus'un cevabında olduğu gibi ), ancak bu muhtemelen bir "dosya listesi çok uzun" hatasına neden olabilir. En iyi yol, katran -Tseçeneği ile birleştirmektir , örneğin:

find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

Temel olarak , dizininizin altındaki tüm dosyaları ( -type f), links ( -type l) ve alt dizinleri ( -type d) listeler , tüm dosya adlarını göreceli olarak kullanarak yapar -printf "%P\n"ve daha sonra tar komutuna iletir (STDIN kullanarak dosya adlarını alır -T -). -CSeçeneği göreli adlarla dosyalarının bulunduğu katran bilmesi için gereklidir. --no-recursionBu tar o (çift dosyaları neden olan) arşive anlatılıyor klasörler halinde recurse gelmez yüzden bayrağıdır.

Dosya adları ile özel bir şey yapmanız gerekiyorsa (filtreleme, sembolik bağlantıları izleme vb.), findKomut oldukça güçlüdür ve taryukarıdaki komutun bir kısmını kaldırarak test edebilirsiniz :

$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore

Örneğin, PDF dosyalarını filtrelemek istiyorsanız, ! -name '*.pdf'

$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore

GNU dışı bulma

Komut , sonuçlarını göreli yollarla yazdırmayı söyleyen printf(GNU'da bulunur find) kullanır find. Ancak, GNU'nuz yoksa find, bu yolları göreli hale getirir (ebeveynleri ile birlikte kaldırır sed):

find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

2
Mükemmel cevap. Çok ayrıntılı ve en önemlisi sorunu mükemmel bir şekilde çözüyor.
Alex

16

Bu cevap çoğu durumda işe yarar. Dosya isimleri, örneğin, olduğu gibi katran dosyada saklanır nasıl Ancak dikkat edin ./file1yerine sadece daha file1. BuildRoot paket dosyaları olarak kullanılan tarballs manipüle etmek için bu yöntemi kullanırken bu sorunlara neden olduğunu buldum .

Bir çözüm, bunun dışındaki tüm dosyaları listelemek için bazı Bash glob'larını kullanmaktır ..:

tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *

Bu cevaptan öğrendiğim bir numara .

Eşleşen dosya yoksa artık tar bir hata döndürür ..?* veya .[^.]*yine de çalışır. Hata bir sorunsa (bir komut dosyasında başarılı olup olmadığını kontrol ediyorsanız), bu işe yarar:

shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob

Şimdi kabuk seçenekleriyle uğraşmamıza rağmen, sahip olmanın daha temiz olduğuna karar verebiliriz * gizli dosyalarla eşleşmenin :

shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob

Bu *, geçerli dizindeki kabuk kürelerinizin bulunduğu yerde çalışmayabilir , bu nedenle alternatif olarak şunları kullanın:

shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob

1
Bunu yaptığımda garip hatalar alıyorum tar: start.sh: Cannot stat: No such file or directory. Bundan nasıl kaçınırım?
BrainStone

@BrainStone Aynı sonuçları alıyorum.
mbmast

15
cd my_directory
tar zcvf ../my_directory.tar.gz *

2
Hal gizli dosyalar hakkında açıkça sordu. Ayrıca ihtiyacınız var.
PanCrit

2
-1: Bu, gizli dosyaları katrana eklemez. TBMM'nin cevabına bakın.
dubek

3

Bu bir Unix / Linux sistemiyse ve gizli dosyaları (* tarafından özlenecek) önemsiyorsanız, yapmanız gerekenler:

cd my_directory
tar zcvf ../my_directory.tar.gz * .??*

Windows altında gizli dosyaların neye benzediğini bilmiyorum.


2

Ben aşağıdaki Bash işlevi öneriyoruz (ilk argüman dir yolu, ikinci argüman elde edilen arşiv temel adıdır):

function tar_dir_contents ()
{
    local DIRPATH="$1"
    local TARARCH="$2.tar.gz"
    local ORGIFS="$IFS"
    IFS=$'\n'
    tar -C "$DIRPATH" -czf "$TARARCH" $( ls -a "$DIRPATH" | grep -v '\(^\.$\)\|\(^\.\.$\)' )
    IFS="$ORGIFS"
}

Bu şekilde çalıştırabilirsiniz:

$ tar_dir_contents /path/to/some/dir my_archive

ve my_archive.tar.gzmevcut dizin içinde arşivi oluşturur . Gizli (. *) Öğelerle ve dosya adlarında boşluk bulunan öğelerle çalışır.


2
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..

Bu benim için çalıştı ve tüm dosyaları "." Adlı bir kök dizine koymadan tüm gizli dosyaları içerir. gibi Tomoe cevabı :


1
tar.create() {
        local folder="${1}"

        local tar="$(basename "${folder}")".tar.gz

        cd "${folder}" && tar -zcvf "../${tar}" .; cd - &> /dev/null
}

Misal:

tar.create folder

Rica ederim.


1

İşte benim işime yarayan bu.

tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')

Ayrıca kullanabilirsiniz

tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')

İlk komutta find , my_dir dosya ve alt dizinlerinin listesini döndürür . Ancak, my_dir dizininin kendisi bu listeye '.' -printf parametre de dahil olmak üzere tam yolu kaldırır. '' ve ayrıca hepsi Ancak biçim dizesi içinde '% P' arasında printf bir dosya ve alt dizinleri listesinde kalan yaprakların my_dir ve sonucu lider boşlukla görülebilir bulmak komutu.

Bu TAR için bir sorun olmayacak, ancak bunu düzeltmek istiyorsanız , ikinci komutta olduğu gibi -mindepth 1 ekleyin .


0

Kişi kullanın.

Pax, kullanımdan kaldırılmış bir paket ancak işi mükemmel ve basit bir şekilde yapıyor.

pax -w > mydir.tar mydir

En pratik ve işi + 1 yapıyor
Breno Salgado

bu komut içeriği ile mydir.tar oluşturur: mydir / file1 mydir / file2, tam olarak kaçınılması gereken şeydi.
Alex

0

Bulduğum en basit yol:

cd my_dir && tar -czvf ../my_dir.tar.gz *


1
Gizli dosyalar dahil değildir.
asynts

0
# tar all files within and deeper in a given directory
# with no prefixes ( neither <directory>/ nor ./ )
# parameters: <source directory> <target archive file>
function tar_all_in_dir {
    { cd "$1" && find -type f -print0; } \
    | cut --zero-terminated --characters=3- \
    | tar --create --file="$2" --directory="$1" --null --files-from=-
}

Dosya adlarını boşluk veya diğer olağandışı karakterlerle güvenle işler. İsteğe bağlı -name '*.sql'olarak, dahil edilen dosyaları sınırlamak için find komutuna bir veya benzer bir filtre ekleyebilirsiniz .


-1
 tar -cvzf  tarlearn.tar.gz --remove-files mytemp/*

Klasör mytemp ise, yukarıdakini uygularsanız klasördeki tüm dosyaları sıkıştırır ve kaldırır, ancak yalnız bırakır

 tar -cvzf  tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*

Hariç tutma kalıpları verebilir ve ayrıca alt klasörlere bakmamayı da belirtebilirsiniz


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.