Como alimentar a saída do grep no scp?

1

Eu tenho um arquivo onde cada linha é um nome de arquivo. Conteúdo do arquivo:

file1
file2
file3
...

Eu, então, executo o comando grep para obter um subconjunto da lista de nomes de arquivos.

Como faço para alimentar a saída do comando grep em scp ? Eu brinquei com xargs e $() sem muito sucesso ...

    
por dognar 20.07.2011 / 12:52

3 respostas

1

Não é necessário usar xargs :

for file in $(grep <some-pattern> <filelist>); do scp $file <remote>; done;

Onde

  • <some-pattern> é seu padrão grep
  • <filelist> é sua lista de arquivos
  • <remote> é a sua extremidade remota do comando scp

O loop for itera em cada linha produzida por grep e passa isso para $file , que você pode reutilizar nos comandos executados entre do e done .

Veja também: Guia avançado de script de script: - Loops

    
por 20.07.2011 / 13:12
1

Para iterar uma lista de nomes de arquivos com um nome por linha, você tem várias possibilidades:

  • Use a substituição de comando para trabalhar o arquivo em uma lista de nomes de arquivos dentro do shell. Você precisa tomar precauções, porque você não pode colocar a substituição do comando entre aspas duplas, pois o resultado da substituição do comando precisa ser dividido em palavras. Você precisa desativar globbing e definir IFS para dividir apenas palavras em novas linhas.

    set -f; IFS='
    '
    scp -- $(…) remote.example.com:
    
  • Use o read interno para processar os nomes dos arquivos em um loop. Novamente, você precisa ser cuidadoso, porque read trata as barras invertidas e $IFS caracteres especialmente.

    … | while IFS= read -r x; do scp -- "$x" remote.example.com: done
    
  • Você pode usar o GNU xargs, mas precisa trabalhar com cuidado, porque o xargs espera sua entrada em um formato com cotação estranha. Você deve passar a opção -d '\n' para selecionar explicitamente novas linhas como o separador de entrada e desativar o comportamento especial de espaço em branco e \'" .

    … | xargs -d '\n' -I {} scp {} remote.example.com:
    

    A única vantagem de xargs é que ele pode agrupar vários argumentos em uma chamada até o limite de comprimento da linha de comando, mas isso só funciona se os argumentos forem passados por último para o comando. Você pode conseguir isso através de uma chamada intermediária para sh , mas raramente vale a pena.

    … | xargs -d '\n' sh -c 'scp -- "$@" "$0"' remote.example.com:
    
  • Uma maneira mais fácil de usar xargs é obter uma lista separada por nulo em vez de uma separada por nova linha. Isso requer a opção -0 , que é suportada pelo GNU xargs e também pelo * BSD recente. Como acima, empurrar os argumentos para uma posição não final requer um pouco de trabalho.

    … | tr '\n' '
    set -f; IFS='
    '
    scp -- $(grep -l CONTENT_REGEXP -- $(cat /path/to/filenames.list)) \
        remote.example.com:
    
    ' | xargs -0 sh -c 'scp -- "$@" "$0"' remote.example.com:

A parte seria grep NAME_REGEXP /path/to/filenames.list se você quisesse filtrar os nomes dos arquivos com uma expressão regular. Se você quisesse filtrar o conteúdo do arquivo, use uma das técnicas acima para alimentar os nomes dos arquivos para grep , por exemplo,

grep NAME_REGEXP /path/to/filenames.list |
rsync -a --files-from - . remote.example.com:

Outra possibilidade que ignora as dificuldades do shell é usar a opção rsync e sua --files-from . Supondo que os nomes dos arquivos sejam todos relativos ao diretório atual:

set -f; IFS='
'
scp -- $(…) remote.example.com:
    
por 20.07.2011 / 15:51
0

Use read para analisar a saída linha a linha ( link ); grep <some-pattern> <filelist> | while read file; do scp $file <remote>; done;

    
por 29.05.2018 / 15:50