glop desenleri ile cp gizli dosyaları


13

Durum:

$ mkdir foo && touch foo/.test
$ cp foo/* .
zsh: no matches found: foo/*
(or bash : cp: cannot stat foo/*’: No such file or directory)

Gizli klasörler ve dosyalarla dolu bir dizinim var. Neler oluyor ve çözüm nedir?


dotglobçevrilir globdotstarafından zsh için geçersiz seçenek adıdır bash .

Yanıtlar:


19

Feragat: Bu cevap özellikle Bash ile ilgilidir, ancak çoğu glob kalıpları ile ilgili soru için geçerlidir!

Yıldız karakteri ( *) bir joker karakterdir. Yer alacağı belirli bir karakter kümesi vardır ve ilk karakter nokta ( .) olmak bunlardan biri değildir. Bu, Unix dosya sistemlerinin nasıl çalıştığı nedeniyle, nokta ile başlayan dosyaların "gizli" olduğu düşünülen özel bir durumdur. Bunun anlamı gibi araçlar bu cp, lsaçıkça bunu söylenmedikçe, vb onları "görmek" olmayacak.

Örnekler

Önce bazı örnek veriler oluşturalım.

$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}

Şimdi aşağıdakilere sahibiz:

$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3

Şimdi bazı oyunlar oynayalım. echoBelirli bir komut için belirli bir joker karakterin ( *) nasıl olacağını listelemek için komutu kullanabilirsiniz :

$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3


$ echo reg*
regdir1 regdir2 regfile1 regfile2 regfile3

$ echo .*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2

$ echo .* *
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3

$ echo .dotdir*
.dotdir1 .dotdir2

Davranış değiştiriliyor mu?

Bu tür dosyalara ek olarak aynı zamanda eşleşecek shopt -s dotglobşekilde davranışını değiştirmek için komutu kullanabilirsiniz .*regfile1.dotfile1

bashadam sayfasından alıntı

dotglob If set, bash includes filenames beginning with a `.' in the results 
        of pathname expansion.

Misal:

$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3

Bu davranışı şu komutla geri alabilirsiniz:

$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3

Senin durumun?

Sizin cpiçin kalıpla eşleşen tüm dosyaları kopyalamak istediğinizi söylüyorsunuz *ve herhangi bir dosya yok.

$ cp foo/.* .

Veya fooklasördeki her şeyi istiyorsanız bunu yapabilirsiniz :

$ cp foo .

Veya açık olabilirsiniz:

$ cp foot/.* foo/* .

Brace genişlemesi kullanan daha kompakt bir form bash:

$ cp foo/{.,}* .

İstediğiniz zaman echo, önerilen dosya desenlerinizi (yıldızın bir parçası olduğu şey için süslü bir terim) görmek için hileyi kullanabilirsiniz .

$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3

Dosyaların + diğer dizinleri bir dizin kopyalamak için gidiyoruz arada eğer, genellikle olduğunu, yinelemeli bunu yapmak istiyor -Ranahtarı için cp:

$ cp -R foo/. .

1
Kullanımından bahsetmek isteyebilirsiniz shopt -s dotglob, echo *sonra verir:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Drav Sloan

@DravSloan - öneriniz için teşekkürler. Ekledi.
slm

cp -r foo .muhtemelen kendi kendine cpkopyalamayı reddedeceğinden foo, muhtemelen çalışmaz cp -R foo/. .. ( cp -Rstandart olanı unutmayın ).
Stéphane Chazelas

1
Ayrıca (oldukça makul) unutmayın, zshiçermez .ve ..genişlemesi de .*. Gelen zshbir desen aynı değilse, komut (oldukça makul tekrar) iptal edilir, bu yüzden genel durumda cp foo/{,.}* .hiçbir gizli ya da hiç olmayan gizli dosyaları varsa başarısız olur.
Stéphane Chazelas

7
Bu cevap yalnızca bash için geçerlidir. Asker, cevap çok daha basit ve shoptvar olmayan zsh kullanıyor .
Gilles 'SO- kötü olmayı kes

31

Bununla birlikte zsh, tipik yol D glob niteleyicisini kullanmaktır ([D] ot dosyalarını dahil etmek için):

cp foo/*(D) .

DZsh glob'lu veya onsuz , asla ( .ne ..beklediğiniz gibi) içermez .


4

Kabuk, karakteri çözdüğünde bu dosyalara gizli olarak davranır *, bu nedenle cpbu dosya adlarından hiçbirini bağımsız değişken olarak almaz.

Bunları açıkça belirterek kopyalayabilirsiniz. cp foo/.* .


1

Yapmak istediğiniz şey tüm dosyaları ve dizinleri bir yerden başka bir yere kopyalamaksa, standart rsynckomutu kullanabilirsiniz . Yukarıda verdiğiniz örnekte:

mkdir foo && touch foo/.test
rsync -a foo/ .

foogizli dosyalar ve gizli dizinler dahil tüm içeriğini tekrar tekrar geçerli dizine kopyalar . Sonundaki sondaki eğik çizgi foo/rsync için önemlidir; onunla sadece içeriği fookopyalanır, onsuz da kopyalanır foo. Örneğin:-

mkdir src && mkdir dest && touch src/.test
rsync -a src  dest    // copies 'src' contents to 'dest/src'
rsync -a src/ dest    // copies 'src' contents to 'dest' 

Makineler arasında kopyalama da dahil olmak üzere başka birçok seçenek var.


1

Stéphane Chazelas'ın zsh cevabı , içinde bir glob bulunan tek bir ifade için doğrudur. Ancak, varsayılan olarak tüm ifadeler için ayarlamak isterseniz,

setopt GLOB_DOTS

~/.zshrcKalıcı hale getirmek için içine koyun .

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.