Como posso fornecer uma matriz como um argumento de arquivo para um script, para que cada elemento seja como uma linha em um arquivo?

1

Suponha que um script bash espera que um argumento seja um arquivo. Mas nós temos uma matriz bash e gostaríamos de fornecer a matriz de alguma forma como um argumento para o script, como se houvesse um arquivo cujas linhas são os elementos da matriz. Eu me pergunto como fazer isso?

Para um exemplo simples, eu tenho um script myscrpt contendo um único comando, que espera um argumento de arquivo

cat $1

e eu tenho uma matriz

arr=( 1 3 5 )

e como posso fornecer arr como argumento para o script, como se o argumento fosse realmente um arquivo cujo conteúdo é

1
3
5

faz myscript <(echo "${arr[@]}") work?

Obrigado.

    
por Tim 05.11.2018 / 17:50

2 respostas

1

Se você estiver usando bash ou algum outro shell capaz de matriz, você pode usar uma construção "${var[@]}" type.

a=(one two 'three four' five)
printf "%s\n" "${a[@]}"

Canalize o printf para o que esperar elementos um por linha, por exemplo

printf "%s\n" "${a[@]}" | myscript

É muito importante citar duas vezes a expansão da matriz; caso contrário, o caractere @ será tratado como * e a expansão da matriz será tratada (erroneamente) com a divisão de palavras no espaço em branco.

    
por 05.11.2018 / 23:55
0

Então, você tem seu script (apenas um pouco modificado para adicionar #! -line e aspas em torno da expansão de $1 para suportar a leitura de arquivos com nomes de arquivos incomuns),

#!/bin/sh
cat "$1"

Agora você quer chamar este script com uma matriz

arr=( 1 2 3 4 5 )

para que, em vez de ler um arquivo (que seu script está fazendo), ele leia o valor delimitado por nova linha de seu array, produzindo

1
2
3
4
5

como saída?

É assim que isso pode ser feito:

printf '%s\n' "${arr[@]}" | ./script -

ou

printf '%s\n' "${arr[@]}" | ./script /dev/stdin

Isso passaria - ou /dev/stdin para seu script como o arquivo a ser lido. O cat interpretará - como entrada padrão e, se fornecido /dev/stdin , também lerá da entrada padrão.

Os dados são fornecidos na entrada padrão por printf , que fornece como elementos delimitados por novas linhas da matriz.

O mesmo efeito seria com

( IFS=$'\n'; sh ./script.sh - <<<"${arr[*]}" )

onde os dados são fornecidos por meio de uma string here. Usando "${arr[*]}" , unimos os elementos da matriz em uma única string separada pelo primeiro caractere de $IFS (que definimos como uma nova linha). Estou usando um subshell aqui para evitar a modificação de IFS no ambiente ao redor.

    
por 25.11.2018 / 17:52