Come filtrare i file quando si usa scp per copiare dir ricorsivamente?


99

Ho bisogno di copiare tutti i file .class dal server al locale con tutte le directory riservate. ad esempio server:/usr/some/unknown/number/of/sub/folders/me.class, /usr/project/backup/some/unknown/number/of/sub/folders/me.classil problema è che ci sono molti altri file inutili come i file .svn-base che non voglio. come posso filtrarli così ho solo i scpfile .class?


Mi piace l'opzione rsync menzionata. Non hai menzionato se si tratta di un'operazione una tantum o se la automatizzerai ripetutamente. Per un'operazione una tantum, l'uso giudizioso di find, grep -v, xargs e file temporanei dovrebbe semplificare il lavoro.
user47559

Risposte:


152

Probabilmente consiglierei di usare qualcosa di simile rsyncper questo a causa dei suoi flag includee exclude, ad esempio: -

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/

Alcuni altri flag utili:

  • -r per ricorsivo
  • -a per l'archivio (principalmente tutti i file)
  • -v per un output dettagliato
  • -e per specificare ssh invece del valore predefinito (che dovrebbe essere ssh, in realtà)

4
Comunque per fare in modo che questo ignori le sottocartelle che non contengono * file di classe? (cioè non voglio un mucchio di directory vuote)
Grant Birchmeier

fantastico, e anche questo è velocissimo!
Prasad Chalasani

2
Puoi spiegare --include, not --include = Nelle pagine MAN, ho potuto trovare spiegazioni su --include = ma non
--include

1
L'opzione è -agià inclusa -rsecondo le pagine man di rsync.
Georg Schölly

3
@GrantBirchmeier --prune-empty-dirsrimuoverà le directory vuote.
Elrond1337

74

Per escludere i dotfile nella directory di base:

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

[!.]* è un glob di shell che si espande a tutti i file nella directory di lavoro che non iniziano con un punto.


10
Questa è probabilmente la migliore risposta; usare i glob per filtrare i file è la strada da percorrere.
Yoshua Wuyts

1
Se la tua opzione è limitata a scp come ho fatto io, questo ha sicuramente aiutato.
user28095

3
Ciò indica di escludere file come richiesto, ma come si può ottenere questo risultato per un'intera directory?
Pille

37

Non è presente alcuna funzionalità in scp per filtrare i file. Per cose "avanzate" come questa, consiglio di usare rsync:

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

(questa riga copia rsync dalla cartella distante a quella corrente)

Le versioni recenti del tunnel rsync su una connessione ssh automaticamente per impostazione predefinita.


10

Dato che puoi scpdovresti essere a posto ssh,
scrivi quanto segue o accedi ed esegui ...

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

tornare indietro (logout) al server locale e 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

Se trovi che $(find ...)è troppo lungo per il tuo cambio di catrame,

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

Infine, dato che lo stai tenendo dentro /usr/project/backup/,
perché preoccuparti dell'estrazione? Tieni solo il tar.bz2, con forse una data + un timestamp.


Questo mi ha aiutato. Sono in Windows e sto combattendo cercando di ottenere rsynce sshinstallato sul sistema operativo. Invece, questa è stata una soluzione intelligente. Grazie!
rayryeng

2

Di seguito il comando per i file.

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

  1. L'IP sarà l'indirizzo IP del server di destinazione.
  2. -name "* .log" per i file di inclusione.
  3. \! -name "hs_err_pid2801.log" per escludere i file.
  4. . è la dir.
  5. -type f per il tipo di file.

Di seguito il comando per la directory.

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

puoi personalizzare il comando sopra secondo le tue esigenze.


1

Con l'autenticazione basata su chiave ssh abilitata, il seguente script funzionerebbe.

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

Se vuoi davvero usare scp, c'è un modo indiretto. Di 'che vogliamo copiare tutto il file .jpg nella cartella locale' / src 'nella cartella' / dst 'nel server remoto 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
anche le spiegazioni verbali sono utili insieme al codice
con

-1
  1. Copia la cartella di origine in somedir :

    cp -r srcdir somedir

  2. Rimuovi tutti i file non necessari:

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

  3. lancia scp da somedir


perché tutti i voti negativi su questa risposta? Suona come una soluzione definitiva alla domanda.
bcarroll

7
Perché questo copierebbe un mucchio di file non necessari e poi li eliminerebbe, perdendo potenzialmente molto tempo.
Oded

Per un programma che passa attraverso diversi passaggi di compilazione, questo ha davvero molto senso. Potrebbe andare subito prima del passaggio che impacchetta il codice compilato in un file taro zip. Invece, non c'è compressione (scp fa la compressione) e il codice "pacchettizzato" viene copiato.
samvv

vero che @samvv (tutto dipende dalla configurazione, dall'ambiente)
San Jay Falcon

se i file vengono ignorati a causa di vincoli di spazio, ciò spreca spazio oltre che tempo
jake
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.