Dir yinelemeli olarak kopyalamak için scp kullanırken dosyalar nasıl filtrelenir?


99

Tüm .class dosyalarını sunucudan yerel dizine tüm dizin ayrılmış olarak kopyalamam gerekiyor. örneğin server:/usr/some/unknown/number/of/sub/folders/me.classolacak /usr/project/backup/some/unknown/number/of/sub/folders/me.classben istemiyorum böyle .svn-baz dosyaları gibi diğer birçok gereksiz dosya vardır, sorundur. onları nasıl filtreleyebilirim, böylece yalnızca scp.class dosyalarım?


Bahsedilen rsync seçeneğini beğendim. Bunun tek seferlik bir işlem olup olmadığını veya bunu tekrar tekrar otomatik hale getirip getirmeyeceğinizi söylemediniz. Tek seferlik bir işlem için, find, grep -v, xargs ve temporary dosyalarının mantıklı kullanımı bu işi kısa sürede halledebilir.
user47559

Yanıtlar:


152

Muhtemelen ve bayrakları rsyncnedeniyle bunun gibi bir şey kullanmanızı tavsiye ederim , örneğin: -includeexclude

rsync -rav -e ssh --include '*/' --include='*.class' --exclude='*' \
server:/usr/some/unknown/number/of/sub/folders/ \ 
/usr/project/backup/some/unknown/number/of/sub/folders/

Diğer bazı yararlı işaretler:

  • -r özyinelemeli
  • -a arşiv için (çoğunlukla tüm dosyalar)
  • -v ayrıntılı çıktı için
  • -e varsayılan yerine ssh belirtmek için (aslında ssh olmalıdır)

4
Her neyse, bunun içinde * sınıf dosyaları olmayan alt klasörleri yoksaymasını sağlamak için? (yani bir sürü boş dizin istemiyorum)
Grant Birchmeier

harika, ve bu da çok hızlı!
Prasad Chalasani

2
Açıklayabilir misiniz --include, not --include = MAN sayfalarında, --include = ama --include
bazz'da

1
Seçenek -azaten -rrsync man sayfalarına göre içerir .
Georg Schölly

3
@GrantBirchmeier --prune-empty-dirsboş dizinleri kaldıracaktır.
Elrond1337

75

Temel dizinde nokta dosyalarını hariç tutmak için:

scp -r [!.]* server:/path/to/something

[!.]* çalışma dizinindeki nokta ile başlamayan tüm dosyalara genişleyen bir kabuk glob'udur.


10
Bu muhtemelen en iyi cevaptır; Dosyaları filtrelemek için glob kullanmak gitmenin yoludur.
Yoshua Wuyts

1
Eğer seçeneğiniz benim sahip olduğum gibi scp ile sınırlıysa, bu kesinlikle yardımcı oldu.
user28095

3
Bu, istenildiği gibi dosyaların dışlanacağını gösterir, ancak bu tüm bir dizin için nasıl başarılabilir?
Pille

Zsh için:scp -r [\!.]* server:/path/to/something
Michael Bar-Sinai

37

Scp'de dosyaları filtrelemek için bir özellik yoktur. Bunun gibi "gelişmiş" şeyler için rsync kullanmanızı tavsiye ederim:

rsync -av --exclude '*.svn' user@server:/my/dir .

(bu satır rsync'i uzak klasörden şu anki klasöre kopyalar)

Varsayılan olarak otomatik olarak bir ssh bağlantısı üzerinden rsync tünelinin son sürümleri.


10

Eğer beri scpsize ok olmalıdır ssh,
ya komut dosyası aşağıdaki ya da giriş ve çalıştırma ...

# After reaching the server of interest
cd /usr/some/unknown/number/of/sub/folders
tar cfj pack.tar.bz2 $(find . -type f -name *.class)

yerel sunucuya (çıkış) geri dönmek ve scp,

# from the local machine
cd /usr/project/backup/some/unknown/number/of/sub/folders
scp you@server:/usr/some/unknown/number/of/sub/folders/pack.tar.bz2 .
tar xfj pack.tar.bz2

Eğer bulursanız $(find ...)için katran değişim için çok uzun,

find . -type f -name *.class | xargs tar cfj pack.tar.bz2

Son olarak, onu içeride tuttuğunuza göre /usr/project/backup/,
neden çıkarma zahmetine giresiniz? Sadece tar.bz2, belki bir tarih + saat damgasıyla birlikte saklayın .


Bu bana yardımcı oldu. Windows'tayım ve işletim sistemini kurmaya rsyncve yüklemeye çalışıyorum ssh. Bunun yerine, bu akıllıca bir çözümdü. Teşekkürler!
rayryeng

2

Dosyalar için aşağıdaki komut.

scp `bul. -maxdepth 1 -name "* .log" \! -name "hs_err_pid2801.log" -tip f` root @ IP: / tmp / test /

  1. IP, hedef sunucu IP adresi olacaktır.
  2. -name "* .log" içerme dosyaları için.
  3. \! dosyaları dışlamak için "hs_err_pid2801.log" adı.
  4. . güncel çalışma dir.
  5. dosya türü için -tip f.

Dizin için komutun altında.

scp -r `bul. -maxdepth 1 -name "lo *" \! -name "localhost" -tip d` root @ IP: / tmp / test /

Yukarıdaki komutu ihtiyacınıza göre özelleştirebilirsiniz.


1

Ssh anahtar tabanlı kimlik doğrulaması etkinleştirildiğinde, aşağıdaki komut dosyası çalışacaktır.

for x in `ssh user@remotehost 'find /usr/some -type f -name *.class'`; do y=$(echo $x|sed 's/.[^/]*$//'|sed "s/^\/usr//"); mkdir -p /usr/project/backup$y; scp $(echo 'user@remotehost:'$x) /usr/project/backup$y/; done

1

Gerçekten scp kullanmak istiyorsanız, dolaylı bir yol var. '/ Src' yerel klasörü altındaki tüm .jpg dosyalarını uzak sunucu 10.1.1.2'deki '/ dst' klasörüne kopyalamak istediğimizi varsayalım:

#make a clean temp folder
mkdir /tmp/ttt
#copy all .jpg file and retain folder structure as-is
find /src -type f -name *.jpg -exec cp --parents \{\} /tmp/ttt \;
#copy to remote target folder as-is and retain original time attributes
scp -rp /tmp/ttt/* 10.1.1.2:/dst
#if copy ok, remove temp folder
rm -rf /tmp/ttt

0
scp -i /home/<user>/.ssh/id_rsa -o "StrictHostKeyChecking=no" -rp /source/directory/path/[!.]* <target_user>@<target_system:/destination/directory/path

1
sözlü açıklamalar da kod ile birlikte faydalıdır
con

-1
  1. Kaynak klasörünüzü şuraya kopyalayın somedir:

    cp -r srcdir somedir

  2. Gereksiz tüm dosyaları kaldırın:

    somedir -name '.svn' -exec rm -rf {} \ + bul

  3. scp'yi başlat somedir


neden bu yanıttaki tüm olumsuz oylar? Bu, soruya bir çözüm yolu gibi geliyor.
bcarroll

7
Çünkü bu, bir sürü gereksiz dosyayı kopyalayıp daha sonra onları silerek potansiyel olarak çok fazla zaman harcayacaktır.
Oded

Birkaç derleme adımından geçen bir program için bu aslında çok mantıklı. Derlenen kodu bir tarveya zip-file içine paketleyen adımın hemen öncesine gidebilir . Bunun yerine, sıkıştırma yoktur (sıkıştırmayı scp yapar) ve 'paketlenmiş' kod kopyalanır.
samvv

@samvv olduğu doğru (hepsi kuruluma, ortama bağlıdır)
San Jay Falcon

dosyalar alan kısıtlamaları nedeniyle göz ardı ediliyorsa, bu zaman kadar alanı da boşa harcıyor
jake
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.