Função write bash que opera na lista de nomes de arquivos

3

Eu quero definir a função cpfromserver no bash para que quando eu corro

$ cpfromserver xxx yyy zzz

o resultado é o mesmo que se eu tivesse digitado

$ scp [email protected]:"/some/location/xxx/xxx.txt /some/location/xxx/xxx.pdf /some/location/yyy/yyy.txt /some/location/yyy/yyy.pdf /some/location/zzz/zzz.txt /some/location/zzz/zzz.pdf" /somewhere/else/

onde funciona para qualquer número de argumentos.

(Ou seja, a função deve copiar filename.txt e filename.pdf do diretório /some/location/filename/ no remote.server para o diretório local /somewhere/else/ para cada filename que eu especificar como um argumento para a função. E faça tudo em uma única conexão ssh .)

Atualmente, eu escrevi uma função que funciona para um único argumento, e apenas faço um loop sobre ela, mas isto estabelece conexões ssh separadas para cada argumento, o que é indesejável.

Minha dificuldade é que eu só sei usar argumentos de função individualmente por sua posição ( $1 , $2 , etc.) - não como manipular toda a lista.

[Note que estou escrevendo essa função como uma ferramenta de conveniência apenas para meu próprio uso, e assim eu priorizaria minha própria facilidade de compreensão sobre como lidar com casos patológicos como nomes de arquivos com aspas ou quebras de linha neles e outros enfeites. Eu sei que os nomes de arquivos com os quais eu vou usar são bem comportados.]

    
por thecommexokid 10.02.2015 / 18:58

3 respostas

4

Tente desta maneira:

cpfromserver () {
    files=''
    for x in "$@"
    do
        files="$files /some/location/$x/$x.txt /some/location/$x/$x.pdf"
    done
    scp [email protected]:"$files" /somewhere/else/
}

Advertência importante dos comentários : "É importante notar que esta solução definitivamente não funcionará para nomes de arquivos complicados. Se um nome de arquivo contiver um espaço, uma nova linha ou citações, essa abordagem definitivamente falhar. "

    
por 10.02.2015 / 19:14
1

Aqui um exemplo simples:

#!/bin/bash

files_to_copy=''
destination_directory=''

while (("$#")) ; do
  if [[ "$@" = "$1" ]] ; then
    # last argument
    destination_directory="$1"
  else
    # argument
    files_to_copy="$files_to_copy $1"
  fi
  shift
done

scp [email protected]:"$files_to_copy" $destination_directory;

Se você executar ./example.sh foo.pdf foo.txt foo.jpg backup/ , deverá obter:

# this will be executed
scp [email protected]:" foo.pdf foo.txt foo.jpg" backup/
    
por 10.02.2015 / 19:24
-1

A idéia principal é preparar string com a lista de arquivos para operar (mesmo através do loop) do que transferir a string para o comando:

sloc='/some/location'
unset flist
for i in "$@"
do
    flist[${#flist[*]}]="$sloc/$i/$i".pdf
    flist[${#flist[*]}]="$sloc/$i/$i".txt
done
scp [email protected]:"${flist[@]}" /somewhere/else/
    
por 10.02.2015 / 19:20