Como filtrar arquivos ao usar scp para copiar dir recursivamente?


99

Preciso copiar todos os arquivos .class do servidor para o local com todos os dir reservados. por exemplo server:/usr/some/unknown/number/of/sub/folders/me.class, será que /usr/project/backup/some/unknown/number/of/sub/folders/me.classo problema é, há muitos outros arquivos inúteis, como arquivos .svn-base que eu não quero. como posso filtrá-los para que eu apenas scpos arquivos .class?


Eu gosto da opção rsync mencionada. Você não mencionou se esta é uma operação única ou se a automatizará repetidamente. Para uma operação única, o uso criterioso de find, grep -v, xargs e arquivos temporários deve simplificar o trabalho.
user47559

Respostas:


152

Eu provavelmente recomendaria usar algo assim rsyncdevido a seus sinalizadores includee exclude, por exemplo: -

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/

Algumas outras sinalizações úteis:

  • -r para recursivo
  • -a para arquivo (principalmente todos os arquivos)
  • -v para saída detalhada
  • -e para especificar ssh em vez do padrão (que deve ser ssh, na verdade)

4
De qualquer forma, para fazer isso ignorar as subpastas que não possuem * arquivos de classe? (ou seja, eu não quero um monte de dirs vazios)
Grant Birchmeier

incrível, e isso é incrivelmente rápido também!
Prasad Chalasani de

2
Você pode explicar --include, não --include = Nas páginas MAN, eu poderia encontrar uma explicação sobre --include = mas não
--include

1
A opção -ajá inclui de -racordo com as páginas de manual do rsync.
Georg Schölly

3
@GrantBirchmeier --prune-empty-dirsremoverá os diretórios vazios.
Elrond1337

74

Para excluir dotfiles do diretório base:

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

[!.]* é um shell glob que se expande para todos os arquivos no diretório de trabalho, não começando com um ponto.


10
Esta é provavelmente a melhor resposta; usar globs para filtrar arquivos é o caminho a percorrer.
Yoshua Wuyts

1
Se sua opção estiver restrita ao scp como eu, isso definitivamente ajudou.
user28095

3
Isso indica a exclusão de arquivos como solicitado, mas como isso pode ser feito para um diretório inteiro?
Pille

37

Não há recurso no scp para filtrar arquivos. Para coisas "avançadas" como esta, recomendo o uso de rsync:

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

(esta linha copia rsync da pasta distante para a atual)

Versões recentes do túnel rsync em uma conexão ssh automaticamente por padrão.


10

Desde que você pode scpvocê deve estar ok para ssh,
qualquer roteiro a seguir ou login e executar ...

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

retornar de volta (logout) ao servidor local 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 você achar que o $(find ...)é muito longo para que seu alcatrão mude para,

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

Finalmente, já que você o está mantendo /usr/project/backup/,
por que se preocupar com a extração? Basta manter o tar.bz2, talvez com um carimbo de data e hora.


Isso me ajudou. Estou no Windows e estou lutando para conseguir rsynce sshinstalar no sistema operacional. Em vez disso, esta foi uma solução alternativa inteligente. Obrigado!
rayryeng

2

Abaixo o comando para arquivos.

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

  1. O IP será o endereço IP do servidor de destino.
  2. -name "* .log" para incluir arquivos.
  3. \! -name "hs_err_pid2801.log" para excluir arquivos.
  4. . é o diretório de trabalho atual.
  5. -type f para o tipo de arquivo.

Abaixo do comando para o diretório.

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

você pode personalizar o comando acima de acordo com sua necessidade.


1

Com a autenticação baseada em chave ssh ativada, o seguinte script funcionaria.

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 você realmente quiser usar scp, há uma maneira indireta. Diga que queremos copiar todos os arquivos .jpg da pasta local '/ src' para a pasta '/ dst' no 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

0
scp -i /home/<user>/.ssh/id_rsa -o "StrictHostKeyChecking=no" -rp /source/directory/path/[!.]* <target_user>@<target_system:/destination/directory/path

1
explicações verbais também são úteis junto com o código
com

-1
  1. Copie sua pasta de origem para somedir:

    cp -r srcdir somedir

  2. Remova todos os arquivos desnecessários:

    encontre algumedir -nome '.svn' -exec rm -rf {} \ +

  3. lançar scp de somedir


por que todos os votos negativos nesta resposta? Isso soa como uma solução direta para a questão.
bcarroll de

7
Porque isso iria copiar um monte de arquivos desnecessários e, em seguida, excluí-los, desperdiçando potencialmente muito tempo.
Oded de

Para um programa que passa por várias etapas de compilação, isso realmente faz muito sentido. Ele pode ir imediatamente antes da etapa que compacta o código compilado em um arquivo tarou zip. Em vez disso, não há compressão (scp faz a compressão) e o código 'empacotado' é copiado.
samvv

verdade que @samvv (tudo depende da configuração, ambiente)
San Jay Falcon

se os arquivos estão sendo ignorados por causa de restrições de espaço, isso desperdiça espaço e tempo
jake
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.