Jak filtrować pliki podczas używania scp do rekurencyjnego kopiowania katalogu?


99

Muszę skopiować wszystkie pliki .class z serwera na lokalny, zachowując cały katalog zarezerwowany. np. server:/usr/some/unknown/number/of/sub/folders/me.classbędzie /usr/project/backup/some/unknown/number/of/sub/folders/me.classproblem, jest wiele innych bezużytecznych plików, takich jak pliki .svn-base, których nie chcę. jak mogę je filtrować, więc tylko scppliki .class?


Podoba mi się wspomniana opcja rsync. Nie wspomniałeś, czy jest to jednorazowa operacja, czy też będziesz ją wielokrotnie automatyzować. W przypadku jednorazowej operacji, rozsądne użycie poleceń find, grep -v, xargs i plików tymczasowych powinno szybko załatwić sprawę.
user47559

Odpowiedzi:


152

Prawdopodobnie poleciłbym użycie czegoś takiego rsyncze względu na jego includei excludeflagi, np: -

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/

Kilka innych przydatnych flag:

  • -r dla rekurencyjnych
  • -a do archiwum (głównie wszystkie pliki)
  • -v dla pełnych informacji wyjściowych
  • -e aby określić ssh zamiast domyślnego (właściwie powinno to być ssh)

4
W każdym razie, aby ignorować podfoldery, które nie zawierają plików * klas? (tj. nie chcę kilku pustych reżerów)
Grant Birchmeier

super, i to też jest niesamowicie szybkie!
Prasad Chalasani,

2
Czy możesz wyjaśnić --include, not --include = Na stronach MAN mogłem znaleźć wyjaśnienie na temat --include = ale nie --include
bazz

1
Zgodnie ze stronami podręcznika rsync opcja -ajuż zawiera -r.
Georg Schölly

3
@GrantBirchmeier --prune-empty-dirsusunie puste katalogi.
Elrond1337

75

Aby wykluczyć dotfiles w katalogu podstawowym:

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

[!.]* jest globalną powłoką, która rozwija się do wszystkich plików w katalogu roboczym, a nie zaczyna się od kropki.


10
To prawdopodobnie najlepsza odpowiedź; użycie globów do filtrowania plików jest drogą do zrobienia.
Yoshua Wuyts

1
Jeśli twoja opcja jest ograniczona do scp, tak jak ja, to zdecydowanie pomogło.
user28095

3
Wskazuje to na wykluczenie plików, na przykład pytanie, ale jak można to osiągnąć dla całego katalogu?
Pille

Dla zsh:scp -r [\!.]* server:/path/to/something
Michael Bar-Sinai

37

W scp nie ma funkcji filtrowania plików. W przypadku „zaawansowanych” rzeczy, takich jak ten, zalecam użycie rsync:

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

(ta linia kopiuje rsync z odległego folderu do bieżącego)

Najnowsze wersje tunelu rsync przez połączenie ssh domyślnie automatycznie.


10

Ponieważ możesz scp, powinieneś być w porządku ssh,
wykonaj skrypt lub zaloguj się i wykonaj ...

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

wróć (wylogowania) na serwerze lokalnym i 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

Jeśli okaże się, że $(find ...)jest za długi, aby zmienić format na,

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

Wreszcie, skoro go trzymasz /usr/project/backup/, po co
zawracać sobie głowę ekstrakcją? Po prostu zachowaj tar.bz2, może z datą i znacznikiem czasu.


To mi pomogło. Jestem w systemie Windows i walczę, próbując zainstalować rsynci sshzainstalować w systemie operacyjnym. Zamiast tego było to sprytne obejście. Dzięki!
rayryeng

2

Poniżej polecenie dla plików.

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

  1. IP będzie adresem IP serwera docelowego.
  2. -name „* .log” dla plików dołączanych.
  3. \! -name „hs_err_pid2801.log” dla plików wykluczeń.
  4. . obecnie działa reż.
  5. -type f dla typu pliku.

Poniżej polecenie dla katalogu.

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

możesz dostosować powyższe polecenie zgodnie z wymaganiami.


1

Po włączeniu uwierzytelniania opartego na kluczu ssh działałby następujący skrypt.

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

Jeśli rzeczywiście chcesz używać scp, istnieje pośredni sposób. Powiedzmy, że chcemy skopiować cały plik .jpg z folderu lokalnego „/ src” do folderu „/ dst” na serwerze zdalnym 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
pomocne są również wyjaśnienia słowne wraz z kodem
con

-1
  1. Skopiuj folder źródłowy do somedir:

    cp -r srcdir somedir

  2. Usuń wszystkie niepotrzebne pliki:

    znajdź katalog -nazwa '.svn' -exec rm -rf {} \ +

  3. uruchom scp z somedir


skąd te wszystkie głosy przeciw tej odpowiedzi? Brzmi to jak bezpośrednie rozwiązanie tego pytania.
bcarroll

7
Ponieważ spowodowałoby to skopiowanie zbędnych plików, a następnie ich usunięcie, tracąc potencjalnie dużo czasu.
Oded

W przypadku programu, który przechodzi przez kilka etapów kompilacji, ma to sens. Może nastąpić tuż przed krokiem, który pakuje skompilowany kod do pliku tarlub zip-file. Zamiast tego nie ma kompresji (scp wykonuje kompresję), a „spakowany” kod jest kopiowany.
samvv

prawda, że ​​@samvv (wszystko zależy od konfiguracji, środowiska)
San Jay Falcon,

jeśli pliki są ignorowane z powodu ograniczeń przestrzennych, marnuje to miejsce i czas
jake
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.