Comment filtrer les fichiers lors de l'utilisation de scp pour copier dir récursivement?

99

J'ai besoin de copier tous les fichiers .class du serveur vers le local avec tous les répertoires réservés. par exemple server:/usr/some/unknown/number/of/sub/folders/me.class, /usr/project/backup/some/unknown/number/of/sub/folders/me.classle problème est qu'il existe de nombreux autres fichiers inutiles tels que les fichiers .svn-base que je ne veux pas. comment puis-je les filtrer pour ne que les scpfichiers .class?

derrdji
la source
J'aime l'option rsync mentionnée. Vous n'avez pas mentionné s'il s'agit d'une opération ponctuelle ou si vous allez l'automatiser à plusieurs reprises. Pour une opération ponctuelle, l'utilisation judicieuse de find, grep -v, xargs et des fichiers temporaires devrait y remédier.
user47559

Réponses:

152

Je recommanderais probablement d'utiliser quelque chose comme rsyncpour cela en raison de ses indicateurs includeet exclude, par exemple: -

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/

Quelques autres indicateurs utiles:

  • -r pour récursif
  • -a pour l'archive (principalement tous les fichiers)
  • -v pour une sortie verbeuse
  • -e pour spécifier ssh au lieu de la valeur par défaut (qui devrait être ssh, en fait)
Gavin Gilmour
la source
4
Quoi qu'il en soit, faire ignorer les sous-dossiers qui ne contiennent pas de fichiers * class? (ie je ne veux pas un tas de dirs vides)
Grant Birchmeier
génial, et c'est méchant vite aussi!
Prasad Chalasani
2
Pouvez-vous expliquer --include, not --include = Dans les pages MAN, je pourrais trouver des explications sur --include = mais pas --include
bazz
1
L'option -ainclut déjà -rselon les pages de manuel rsync.
Georg Schölly
3
@GrantBirchmeier --prune-empty-dirssupprimera les répertoires vides.
Elrond1337
75

Pour exclure les fichiers dot dans le répertoire de base:

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

[!.]* est un shell glob qui s'étend à tous les fichiers du répertoire de travail ne commençant pas par un point.

rgtk
la source
10
C'est probablement la meilleure réponse; utiliser des globs pour filtrer les fichiers est la voie à suivre.
Yoshua Wuyts
1
Si votre option est limitée à scp comme je l'avais fait, cela a vraiment aidé.
user28095
3
Cela indique d'exclure des fichiers comme on vous le demande, mais comment cela peut-il être réalisé pour un répertoire entier?
Pille
Pour zsh:scp -r [\!.]* server:/path/to/something
Michael Bar-Sinai
37

Il n'y a pas de fonctionnalité dans scp pour filtrer les fichiers. Pour des trucs "avancés" comme celui-ci, je recommande d'utiliser rsync:

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

(cette ligne copie rsync du dossier distant vers le dossier actuel)

Les versions récentes du tunnel rsync via une connexion ssh automatiquement par défaut.

Ville Laurikari
la source
10

Puisque vous pouvez, scpvous devriez être d'accord ssh,
soit écrire ce qui suit, soit vous connecter et exécuter ...

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

revenir (déconnexion) au serveur local et 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

Si vous trouvez que $(find ...)c'est trop long pour votre changement de goudron,

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

Enfin, puisque vous le gardez /usr/project/backup/,
pourquoi s'embêter à l'extraction? Gardez simplement le tar.bz2, avec peut-être un horodatage.

nik
la source
Cela m'a aidé. Je suis sous Windows et je me bats pour essayer d'obtenir rsyncet de l' sshinstaller sur le système d'exploitation. Au lieu de cela, c'était une solution de contournement intelligente. Merci!
rayryeng
2

Commande ci-dessous pour les fichiers.

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

  1. IP sera l'adresse IP du serveur de destination.
  2. -name "* .log" pour les fichiers d'inclusion.
  3. \! -name "hs_err_pid2801.log" pour les fichiers d'exclusion.
  4. . est le répertoire de travail actuel.
  5. -type f pour le type de fichier.

Commande ci-dessous pour le répertoire.

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

vous pouvez personnaliser la commande ci-dessus selon vos besoins.

Suneet Khurana
la source
1

Avec l'authentification basée sur la clé ssh activée, le script suivant fonctionnerait.

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
Varun
la source
1

Si vous voulez vraiment utiliser scp, il existe un moyen indirect. Dites que nous voulons copier tous les fichiers .jpg du dossier local '/ src' dans le dossier '/ dst' du serveur distant 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
Scott Chu
la source
0
scp -i /home/<user>/.ssh/id_rsa -o "StrictHostKeyChecking=no" -rp /source/directory/path/[!.]* <target_user>@<target_system:/destination/directory/path
Vinay Babu
la source
1
les explications verbales sont également utiles avec le code
con
-1
  1. Copiez votre dossier source dans somedir:

    cp -r srcdir somedir

  2. Supprimez tous les fichiers inutiles:

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

  3. lancer scp depuis somedir

dfa
la source
pourquoi tous les votes négatifs sur cette réponse? Cela ressemble à une solution via la question.
bcarroll
7
Parce que cela copierait un tas de fichiers inutiles puis les supprimerait, ce qui ferait potentiellement perdre beaucoup de temps.
Oded
Pour un programme qui passe par plusieurs étapes de compilation, cela a en fait beaucoup de sens. Cela pourrait aller juste avant l'étape qui rassemble le code compilé dans un fichier tarou zip-file. Au lieu de cela, il n'y a pas de compression (scp fait la compression) et le code «packagé» est copié.
samvv
vrai que @samvv (tout dépend de la configuration, de l'environnement)
San Jay Falcon
si les fichiers sont ignorés en raison de contraintes d'espace, cela gaspille de l'espace ainsi que du temps
jake