¿Cómo filtrar archivos cuando se usa scp para copiar dir de forma recursiva?

99

Necesito copiar todos los archivos .class del servidor al local con todos los directorios reservados. Por ejemplo server:/usr/some/unknown/number/of/sub/folders/me.class, /usr/project/backup/some/unknown/number/of/sub/folders/me.classel problema es que hay muchos otros archivos inútiles, como archivos .svn-base, que no quiero. ¿Cómo puedo filtrarlos para que solo scptenga archivos .class?

derrdji
fuente
Me gusta la opción rsync mencionada. No mencionaste si se trata de una operación única o si la automatizarás repetidamente. Para una operación única, el uso juicioso de find, grep -v, xargs y archivos temporales debería hacer que esto sea más fácil.
user47559

Respuestas:

152

Probablemente recomendaría usar algo como rsyncesto debido a sus banderas includey exclude, por ejemplo: -

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/

Algunas otras banderas útiles:

  • -r por recursivo
  • -a para archivo (principalmente todos los archivos)
  • -v para una salida detallada
  • -e para especificar ssh en lugar del predeterminado (que debería ser ssh, en realidad)
Gavin Gilmour
fuente
4
De todos modos, ¿hacer que esto ignore las subcarpetas que no tienen archivos * de clase en ellas? (es decir, no quiero un montón de directorios vacíos)
Grant Birchmeier
impresionante, y esto también es perverso!
Prasad Chalasani
2
¿Puede explicar --include, no --include = En las páginas de MAN, pude encontrar una explicación sobre --include = pero no --include
bazz
1
La opción -aya incluye -rsegún las páginas del manual de rsync.
Georg Schölly
3
@GrantBirchmeier --prune-empty-dirseliminará los directorios vacíos.
Elrond1337
74

Para excluir archivos dot en el directorio base:

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

[!.]* es un globo de shell que se expande a todos los archivos en el directorio de trabajo que no comienzan con un punto.

rgtk
fuente
10
Esta es probablemente la mejor respuesta; usar globs para filtrar archivos es el camino a seguir.
Yoshua Wuyts
1
Si su opción está restringida a scp como yo, esto definitivamente ayudó.
user28095
3
Esto indica que se deben excluir archivos como si se les preguntara, pero ¿cómo se puede lograr esto para un directorio completo?
Pille
37

No hay ninguna función en scp para filtrar archivos. Para cosas "avanzadas" como esta, recomiendo usar rsync:

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

(esta línea copia rsync de la carpeta distante a la actual)

Versiones recientes del túnel rsync a través de una conexión ssh automáticamente de forma predeterminada.

Ville Laurikari
fuente
10

Ya que puede scp, debería estar de acuerdo ssh,
ya sea con el siguiente script o inicie sesión y ejecute ...

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

volver (cerrar sesión) al servidor local y 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 encuentra que $(find ...)es demasiado largo para que su alquitrán cambie a,

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

Finalmente, ya que lo está guardando /usr/project/backup/,
¿por qué molestarse en la extracción? Solo mantén el tar.bz2, quizás con un sello de fecha y hora.

nik
fuente
Eso me ayudó. Estoy en Windows y estoy luchando por intentar instalarlo rsynce sshinstalarlo en el sistema operativo. En cambio, esta fue una solución inteligente. ¡Gracias!
rayryeng
2

Debajo del comando para archivos.

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

  1. La IP será la dirección IP del servidor de destino.
  2. -nombre "* .log" para incluir archivos.
  3. \! -nombre "hs_err_pid2801.log" para excluir archivos.
  4. . es el directorio de trabajo actual.
  5. -type f para el tipo de archivo.

Debajo del comando para el directorio.

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

Puede personalizar el comando anterior según sus necesidades.

Suneet Khurana
fuente
1

Con la autenticación basada en clave ssh habilitada, el siguiente script funcionaría.

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
fuente
1

Si realmente desea usar scp, hay una forma indirecta. Digamos que queremos copiar todo el archivo .jpg en la carpeta local '/ src' a la carpeta '/ dst' en el servidor 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
Scott Chu
fuente
0
scp -i /home/<user>/.ssh/id_rsa -o "StrictHostKeyChecking=no" -rp /source/directory/path/[!.]* <target_user>@<target_system:/destination/directory/path
Vinay Babu
fuente
1
Las explicaciones verbales también son útiles junto con el código
con
-1
  1. Copie su carpeta de origen en somedir:

    cp -r srcdir somedir

  2. Elimine todos los archivos innecesarios:

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

  3. lanzar scp desde somedir

dfa
fuente
¿Por qué todos los votos negativos en esta respuesta? Esto suena como una solución a la pregunta.
bcarroll
7
Porque esto copiaría un montón de archivos innecesarios y luego los eliminaría, perdiendo potencialmente mucho tiempo.
Oded
Para un programa que pasa por varios pasos de compilación, esto tiene mucho sentido. Podría ir justo antes del paso que empaqueta el código compilado en un archivo taro zip. En cambio, no hay compresión (scp realiza la compresión) y el código 'empaquetado' se copia.
samvv
es cierto que @samvv (todo depende de la configuración, el entorno)
San Jay Falcon
si los archivos se ignoran debido a limitaciones de espacio, esto desperdicia espacio y tiempo
jake