Dosyaları taşımak ve kullanıcıdan yinelenen adlar olup olmadığını sormak:
As Subv3rsion en ve Eric Leschinski en cevapları göstermek, -newermt
yüklem seçer dosyalar kendi işlenen olarak belirtilen tarih (ve isteğe bağlı saat) daha son değiştirilen. Dosyaları bulmak
- herhangi bir yerde
srcdir
(yani, alt dizinleri, alt dizinleri vb. dahil)
- en son değiştirilme tarihi (örneğin) Eylül 2014
- ve taşımak için
destdir
...koşabilirsin:
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;
Bir -exec
ifadede, find yerine bulunan dosya adını iletir {}
. Çalıştırılacak komutun ve argümanlarının hepsinin sağlanmış olduğunu ;
belirtir -exec
(sonraki ifadelerin, bu belirli -exec
yüklemenin argümanlarından sonra bulmak için geçmesi durumunda - bunun için aşağıya bakınız). ;
kaçması gerekir, \;
bu yüzden kabuk tarafından özel olarak yorumlanmamıştır. (Olmadan \
, ;
tüm find
komutu sonlandıracak, yeni bir satırla aynı şekilde çalışacak. Bu find
komutun bu -exec
ifadeden sonra hiçbir şeyi olmamasına rağmen , ;
argümanı geçememek yine de sözdizimi hatasıdır.)
Dosyaları yalnızca listelemek istiyorsanız - eski e-postaların nasıl depolandığından veya başka hangi dosyaların mevcut olabileceğinden emin değilseniz önerilir - atlar -exec
ve her şey için bu hakkı sağlayın . (E-posta için, genellikle farklı tarihlerden gelen e-postalar aynı dosyada saklanır ; burada sorulan durumda olan biri için, herhangi bir dosyayı taşımadan önce nasıl depolandıklarını araştırmanızı öneririm.) Hem adlarını yazdırmak hem de taşımak onları daha -print
önce ekleyin -exec
.
mv -i
Bir dosyanın hedefe yazılacağı herhangi bir zamanda sorulur, örneğin:
- aynı adda bir dosya önceki bir yedekten var veya
- aynı adda ancak farklı bir alt dizininden bir dosya
srcdir
aynı find
işlem sırasında çoktan taşındı veya
- (en azından muhtemel) aynı adda bir dosya
srcdir
, aynı find
işlem sırasında , orijinaller taşındıktan sonra, ancak find
bir zamanlar farklı bir alt dizine geçtiğinde, yeterince kısa sürede bulunacak bir yerde yaratıldı .
Çağırmanın diğer yolları rm
:
Çift isimleri olan dosyaların nasıl kullanılacağı konusunda başka seçenekleriniz de var.
- Olmadan
-i
(yani ), genellikle onay istenmez, ancak hedef dosya salt okunur olsaydı bunu yapardı. ( bazen dosyayı çalıştıran kullanıcı gibi) salt okunur bir dosyanın üzerine yazmayı bile başarabilir.)mv {} destdir/
mv
mv
- Bu derecede bir etkileşim derecesi istemiyorsanız ve
mv
her zaman aynı adlandırılmış dosyaların üzerine yazmak (denemek) istiyorsanız , kullanın mv -f
.
- Buna karşılık, aynı adı taşıyan bir hedef dosya zaten varsa, kaynak dosyaları atlamak istiyorsanız, kullanın
mv -n
.
mv
Hedefte zaten var olan özdeş adları taşıyan dosyaları otomatik olarak yeniden adlandırmak için -b
ve --backup
bayrakları kabul eder . ~
Yedekleme adını üretmek için varsayılan olarak eklenir ve hedefte adın bulunduğu bir dosya ve yedek adının bulunduğu bir dosya varsa, yedekleme dosyasının üzerine yazılır. Bu varsayılan, çağrılırken geçirilen seçeneklerle mv
ve ortam değişkenleriyle geçersiz kılınabilir . Ayrıntılar man mv
ve aşağıdaki örneğe bakın.
Tekrarlanan adlar durumunda dosyaları taşıma ve yedeklemeler oluşturma:
Tüm dosyaları taşımak, dosyaları bir ~
sonek kullanarak yinelenen adlarla yedekleyin ve dosyalar zaten varsa (herhangi bir şeyin üzerine yazılmasını önlemek için) numaralı sonekleri kullanın..~n~
.~
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;
Dosyaları yinelenen adlarla atladıysanız ve hangilerinin olduğunu bilmek istiyorsanız:
Eğer kullanırsanız mv -n
ve aynı adla başka bir dosya olduğu için taşınmaz hangi dosyaların bilmek istiyorum, en iyi yolu sadece orijinal çalıştırmak için muhtemelen find
olmadan tekrar komutu -exec
sağında ve herşey. Bu isimlerini yazdıracak.
Ayrıca, orijinal find .... -exec ...
komutu çalıştırdığınızdan beri oluşturulan tüm eşleşen dosyaların adlarını da yazdıracaktır , ancak bu uygulama için eski değişiklik zamanları olan dosyaları aradığınızdan genellikle hiçbiri olmayacaktır. Bir dosyaya, gerçek yaşından daha eski bir değişiklik zaman damgası touch
ve diğer mekanizmaları vermek mümkündür , ancak bu durumda bilginiz olmadan gerçekleşmesi muhtemel görünmemektedir.
Çift isimler nedeniyle dosyaların hemen atlandığını bilmek:
mv -n
Bir dosyayı taşımaktan kaçındığında, herhangi bir özel çıkış kodunu rapor etmez veya geri göndermez . Bu nedenle, find
çalıştırılırken atlanan dosyalar hakkında derhal haberdar olmak istiyorsanız, bunun için ayrı bir adım atmanız gerekir. Bir yol:
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
-exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;
Muhtemelen küçük teknik hususlar: mv
Bir dosyayı hedefte var olandan farklı bir nedenden kopyalayamazsa ve raporlama başarısından çıkarsa bu yanlış uyarı verir . Bu mümkün görünmüyor, ancak imkansız olduğundan emin değilim. Aynı zamanda potansiyel olarak bir yarış koşuluna da maruz kalır: eski bir dosya taşındıktan kısa bir süre sonra aynı yerde ve aynı zamanda kontrol edilmeden önce aynı yerde yeni bir dosya oluşturulursa, gerçek bir hata olmadığı zaman uyarılır. bakalım çıkarılmış mı. (Uygulamayı göz önünde bulundurarak, herhangi bir sorunun gerçekten ortaya çıkacağından şüpheliyim.) Daha önce hedefi kontrol etmek için yeniden yazılabilirdi.dosyayı sonra yerine taşımak: daha sonra yarış durumu kaynak dosyalar yerine yeni oluşturulan hedef dosyalarla ilgilidir. Ve find
veya mv
(veya [
olmamasına rağmen) bildirilen hatalar ve uyarılar standart hataya yazılırken , ...skipped (exists in...
uyarımız standart çıktıya yazılır . Normalde her ikisi de terminalinizde görünür, ancak komut dosyası kullanıyorsanız bu önemli olabilir.
Daha kolay okumak için bu komutu iki satıra böldüm. Bu şekilde çalıştırılabilir veya \
yeni çizgiyi (yani satır sonu) kaldırabilirsiniz .
Bu find
komut nasıl çalışıyor?
find
Tahminler, geri dönüş değerleri için kullanılan testler (gibi -type
ve -newermt
) veya genellikle yan etkileri için kullanılan eylemler (gibi -print
ve -exec
) olabilir.
Hiçbir (gibi operatör zaman -a
için ve , -o
için ya ) ifadeleri arasındaki beslenir, -a
ima edilir. ve ve veya için kısa devre değerlendirmesifind
uygular . (yani, ) yalnızca p ve q ifadelerinin her ikisi de doğruysa doğrudur, bu nedenle p'nin yanlış olması durumunda q değerlendirilmesine gerek yoktur . Sık sık bu terimlerle düşünmemize rağmen, testlerin sonraki eylemler veya değerlendirilecek testler için doğru olmasının nedeni budur. Örneğin, bir dizinin üstüne geldiğini varsayalım . False olarak değerlendirir , böylece daha sonra her şeyi atlayabilir.p q
p -a q
find
-type f
Testler gibi, eylemler de doğru veya yanlış olarak değerlendirilir. Bu şekilde, -exec
yürütülen komutun raporlama başarısından (doğru) veya başarısızlıktan (yanlış) çıkıp çıkmadığını bildirir. Biz bu zinciri var -exec
örtük ile bağlı ifadeler ve :
-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;
Bu dosyayı taşımaya çalışır ve eğer mv
rapor başarısız olursa durur. Başka bir sorun neden taşınmamışsa, doğru atlanmış bir dosya hakkında uyarmak istemiyoruz.
Fakat başarılı olursa , [
komutu çalıştırır . Mesela find
, [
argüman olarak iletilen kendi ifadelerini destekler. [ -f {} ]
Sonrasında işlenenin -f
(onun find
yerine geçtiği yer {}
) var olup olmadığını denetler (ve normal bir dosyadır) ve doğru / başarı ya da yanlış / başarısızlık döndürür.
(Pek çok komutun çıkış durumları en iyi başarı veya başarısızlık anlamına gelir olarak yorumlanır, ancak [
var olan durumu genellikle en iyi şekilde doğru veya yanlış olarak yorumlanır.)
Eğer [
yanlış döndü ardından dosya o taşındı bu yüzden, bu yüzden herhangi bir şey yapmaya gerek yoktur, gitti. Ancak [
false döndürülürse, dosya hala oradadır. Ardından , uyarı mesajını basan bir find
sonraki -exec
ifadeyi değerlendirir .
Daha fazla okuma