Como passar o conteúdo de um arquivo como múltiplos argumentos no bash

5

Eu tenho um arquivo que contém dados que são atualizados ao longo do tempo (mydata). O arquivo é assim:

1 2 3

Com este arquivo, quero fazer isso (basicamente manipular cada número como um parâmetro separado):

myscript.sh 1 2 3

Como os dados não são estáticos, mas são atualizados com o tempo, quero executar este comando:

myscript.sh "$(cat mydata)"

Mas, em vez disso, vejo ./myscript.sh: linha 1: 1: comando não encontrado

O que devo fazer?

    
por michelemarcon 08.01.2015 / 17:19

3 respostas

5

"$(cat mydata)" avalia uma string que contém o conteúdo do arquivo mydata menos qualquer nova linha à direita. O que você quer é a lista de palavras separadas por espaços em branco no arquivo. Então, pela primeira vez, use a substituição de comando fora de aspas duplas:

myscript.sh $(cat mydata)

Para maior robustez, desative a globbing, para que, se uma coluna em mydata contiver um dos caracteres \[*? , não seja interpretada como um padrão de nome de arquivo. Você também pode definir IFS para conter o caracteres separadores de palavras, mas o padrão (espaço em branco ASCII) deve ser exatamente o que você precisa.

(set -f; myscript.sh $(cat mydata))

Como alternativa, você pode usar o read builtin. Isso lê a primeira linha e ignora o resto (o que você poderia fazer acima substituindo cat por head -n 1 ).

read -r one two three rest <mydata
myscript.sh "$one" "$two" "$three"
    
por 09.01.2015 / 00:31
5

Normalmente, é para isso que xargs :

xargs myscript.sh < mydata

xargs considera a entrada como palavras separadas em branco ou em nova linha, em que aspas simples, aspas duplas ou contrabarra são usadas para escapar dos separadores. xargs executará o comando quantas vezes forem necessárias para evitar o limite no tamanho dos argumentos (e ambiente) passados para um comando.

    
por 09.01.2015 / 17:33
3

Em vez de passar como vários argumentos, apenas passo os argumentos como uma única matriz e, em seguida, faço o que quiser com os argumentos.

#This is the function which takes a variable length array as an input. 
function function_call() 
{
    all_array_values=$1[@]
    a=("${!all_array_values}")
    for i in "${a[@]}" ; do
        echo "$i"
    done
}


#Here I add all the file contents to the variable named input.  
input=$(cat filename)
#In this step I convert the file contents to an array by splitting on space. 
input_to_array=(${input//' '/ })
#I call the function here. 
function_call input_to_array

Teste

Eu tenho o arquivo de entrada como abaixo.

cat filename
1 2 3 4
5
6
7
8

Como você pode ver, usei várias linhas também na entrada para fins de teste.

Agora, quando executo o script acima, recebo a saída abaixo.

1
2
3
4
5
6
7
8

Eu mudo o arquivo de entrada para ter um número menor de argumentos e quando executo os argumentos menores, recebo a saída abaixo.

1
2
3
4

Referências

link link

    
por 08.01.2015 / 17:57