Bagaimana cara memfilter file saat menggunakan scp untuk menyalin dir secara rekursif?


99

Saya perlu menyalin semua file .class dari server ke lokal dengan semua dir yang dipesan. misal server:/usr/some/unknown/number/of/sub/folders/me.classakan jadi /usr/project/backup/some/unknown/number/of/sub/folders/me.classmasalah adalah, masih banyak file tidak berguna lainnya seperti file .svn-base yang tidak saya inginkan. bagaimana cara memfilternya jadi saya hanya scpfile kelas.?


Saya suka opsi rsync yang disebutkan. Anda tidak menyebutkan apakah ini operasi satu kali, atau jika Anda akan mengotomatiskan ini berulang kali. Untuk operasi satu kali, penggunaan file find, grep -v, xargs, dan file sementara yang bijaksana akan mempersingkat pekerjaan ini.
pengguna47559

Jawaban:


152

Saya mungkin akan merekomendasikan menggunakan sesuatu seperti rsyncini karena includedan excludebenderanya, misalnya: -

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/

Beberapa tanda berguna lainnya:

  • -r untuk rekursif
  • -a untuk arsip (kebanyakan semua file)
  • -v untuk keluaran verbose
  • -e untuk menentukan ssh alih-alih default (yang seharusnya ssh, sebenarnya)

4
Pokoknya membuat ini mengabaikan subfolder yang tidak memiliki * file kelas di dalamnya? (yaitu saya tidak ingin banyak dirs kosong)
Grant Birchmeier

mengagumkan, dan ini juga cepat jahat!
Prasad Chalasani

2
Dapatkah Anda menjelaskan --include, bukan --include = Di halaman MAN, saya dapat menemukan penjelasan tentang --include = tetapi tidak
--include

1
Opsi -asudah termasuk -rsesuai dengan halaman manual rsync.
Georg Schölly

3
@GrantBirchmeier --prune-empty-dirsakan menghapus direktori kosong.
Elrond1337

74

Untuk mengecualikan dotfiles di direktori dasar:

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

[!.]* adalah shell glob yang meluas ke semua file di direktori kerja yang tidak dimulai dengan titik.


10
Ini mungkin jawaban terbaik; menggunakan globs untuk memfilter file adalah cara yang harus dilakukan.
Yoshua Wuyts

1
Jika pilihan Anda terbatas pada scp seperti yang saya miliki, ini pasti membantu.
pengguna28095

3
Ini menunjukkan untuk mengecualikan file seperti yang diminta, tetapi bagaimana ini bisa dicapai untuk seluruh direktori?
Pille

37

Tidak ada fitur di scp untuk memfilter file. Untuk hal-hal "lanjutan" seperti ini, saya sarankan menggunakan rsync:

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

(baris ini menyalin rsync dari folder jauh ke folder saat ini)

Versi terbaru dari rsync tunnel melalui koneksi ssh secara otomatis secara default.


10

Karena Anda bisa, scpAnda harusnya baik- baik saja ssh,
skrip yang berikut atau login dan jalankan ...

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

kembali (logout) ke server lokal dan 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

Jika Anda merasa $(find ...)terlalu lama untuk tar Anda berubah,

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

Akhirnya, karena Anda menyimpannya /usr/project/backup/,
mengapa repot-repot mengekstraksi? Simpan saja tar.bz2, mungkin dengan cap tanggal + waktu.


Ini membantu saya. Saya menggunakan Windows dan saya berjuang untuk mencoba rsyncdan sshmenginstal di OS. Sebaliknya, ini adalah solusi yang cerdas. Terima kasih!
rayryeng

2

Di bawah perintah untuk file.

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

  1. IP akan menjadi alamat IP server tujuan.
  2. -name "* .log" untuk menyertakan file.
  3. \! -name "hs_err_pid2801.log" untuk mengecualikan file.
  4. . adalah dir kerja saat ini.
  5. -type f untuk tipe file.

Di bawah perintah untuk direktori.

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

Anda dapat menyesuaikan perintah di atas sesuai kebutuhan Anda.


1

Dengan otentikasi berbasis kunci ssh diaktifkan, skrip berikut akan berfungsi.

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

Jika Anda memang ingin menggunakan scp, ada cara tidak langsung. Katakanlah kami ingin menyalin semua file .jpg di bawah folder lokal '/ src' ke folder '/ dst' di server jauh 10.1.1.2:

#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
penjelasan verbal juga membantu bersama dengan kode
con

-1
  1. Salin folder sumber Anda ke somedir:

    cp -r srcdir somedir

  2. Hapus semua file yang tidak dibutuhkan:

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

  3. luncurkan scp dari somedir


mengapa semua suara negatif pada jawaban ini? Ini terdengar seperti solusi via untuk pertanyaan tersebut.
bcarroll

7
Karena ini akan menyalin banyak file yang tidak perlu lalu menghapusnya, berpotensi membuang banyak waktu.
Oded

Untuk program yang melalui beberapa langkah kompilasi, ini sebenarnya sangat masuk akal. Ini bisa berjalan tepat sebelum langkah yang mengemas kode yang dikompilasi menjadi taratau zip-file. Sebaliknya, tidak ada kompresi (scp melakukan kompresi) dan kode 'paket' disalin.
samvv

benar bahwa @samvv (semua tergantung pada pengaturan, lingkungan)
San Jay Falcon

jika file diabaikan karena keterbatasan ruang, ini akan membuang-buang ruang dan juga waktu
jake
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.