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.