Como leio uma variável de um arquivo?

68

Quero inserir no meu script um valor (string) que eu leria de um arquivo de texto.

Por exemplo, em vez de:

echo "Enter your name"
read name

Quero ler uma string de outro arquivo de texto para que o intérprete leia a string do arquivo e não da entrada do usuário.

user208413
fonte
11
Como é o seu arquivo de texto? O arquivo inteiro 1 é variável ou são KEY=VALUEpares? As soluções são bastante diferentes (se ele é o último, a resposta de Takkat aplica, o ex-Radu de)
kiri
11
@CiroSantilli, ele não é postado de forma cruzada se tiver sido postado por um usuário diferente; não existe uma "duplicata entre sites". A única coisa que deve ser evitada é a mesma pergunta feita pelo mesmo usuário em sites diferentes.
terdon

Respostas:

98

Para ler variáveis ​​de um arquivo, podemos usar o comando sourceou ..

Vamos supor que o arquivo contenha a seguinte linha

MYVARIABLE="Any string"

podemos importar essa variável usando

#!/bin/bash

source <filename>
echo $MYVARIABLE
Takkat
fonte
16
Uma razão pela qual você pode não querer fazer dessa maneira é porque tudo o que estiver dentro <filename>será executado em seu shell, como rm -rf /, o que pode ser muito perigoso.
precisa saber é o seguinte
3
Chegou atrasado à festa, mas, não, não merece ser marcado OU como a resposta. Isso gera outro arquivo de origem do bash que NÃO é o que o OP solicitou. Ele perguntou como ler o conteúdo de um arquivo em uma variável. NÃO como executar outro script que define uma variável . A resposta correta é a abaixo. nome = $ (cat "$ file").
HörmannHH
2
OTOH, é a resposta para a pergunta que fiz ao google e o google me trouxe aqui. Tempos estranhos, não é?
22817 Michael Terry
11
Ótimo também funciona para várias variáveis! O ponto do @MarkRibau é entendido, mas acho que se você corrigir o arquivo em um script diferente e apenas precisar repassá-lo, é bem controlado e controlado.
181917 madlymad
11
Você pode usar sedpara adicionar localpalavras-chave e tornar o script um pouco mais seguro e não poluir seu escopo global. Então, dentro de uma função, faça cat global_variables.sh | sed -e 's/^/local /' > local_variables.she use . ./local_variables.sh. O que você importar na função estará disponível apenas nessa função. Observe que ele assume global_variables.shapenas uma variável por linha.
Nux
55

Considerando que você deseja que todo o conteúdo do seu arquivo de texto seja mantido em sua variável, você pode usar:

#!/bin/bash

file="/path/to/filename" #the file where you keep your string name

name=$(cat "$file")        #the output of 'cat $file' is assigned to the $name variable

echo $name               #test

Ou, em pura festa:

#!/bin/bash

file="/path/to/filename"     #the file where you keep your string name

read -d $'\x04' name < "$file" #the content of $file is redirected to stdin from where it is read out into the $name variable

echo $name                   #test
Radu Rădeanu
fonte
Eu não quero exibir a variável, quero que essa variável seja lida pelo script para processamento adicional. Eu tentei o awk que lê linha por linha.
user208413
11
Ok, exclua echo $name . Eu uso apenas para teste. Em seguida, você pode usar a $namevariável para processamento adicional em qualquer lugar que desejar no seu script.
Radu Rădeanu 28/10
Eu não posso usá-lo em qualquer lugar do meu script porque o script não sabe o valor da variável. No nosso caso, o nome da variável.
user208413
6
@ user208413 O valor da $namevariável é a sequência do seu arquivo atribuída usando o cat $filecomando O que não é claro ou tão difícil de entender?
Radu Rădeanu 28/10
11
É redundante para usar um independentes $filevariável se você estiver usando apenas uma vez para carregar o $namevariável, basta usarcat /path/to/file
kiri
11

De dentro do seu script, você pode fazer isso:

read name < file_containing _the_answer

Você pode fazer isso várias vezes, por exemplo, em um loop

while read LINE; do echo "$LINE"; done < file_containing_multiple_lines
thom
fonte
ou para um arquivo com vários itens em cada linha. . . grep -v ^ # file | enquanto lê abc; faça eco a = $ ab = $ bc = $ c; feito
gaoithe
7

Uma maneira alternativa de fazer isso seria apenas redirecionar a entrada padrão para o seu arquivo, onde você tem toda a entrada do usuário na ordem esperada pelo programa. Por exemplo, com o programa (chamado script.sh)

#!/bin/bash
echo "Enter your name:"
read name
echo "...and now your age:"
read age

# example of how to use the values now stored in variables $name and $age
echo "Hello $name. You're $age years old, right?"

e o arquivo de entrada (chamado input.in)

Tomas
26

você pode executar isso no terminal de uma das seguintes maneiras:

$ cat input.in | ./script.sh
$ ./script.sh < input.in

e seria equivalente a apenas executar o script e inserir os dados manualmente - seria impressa a linha "Olá Tomas. Você tem 26 anos, certo?".

Como Radu Rădeanu tem já foi sugerido , você pode usar catdentro do seu script para ler o conteúdo de um arquivo em um avariable - nesse caso, você precisa de cada arquivo para conter apenas uma linha, com apenas o valor que deseja para essa variável específica. No exemplo acima, você poderia dividir o arquivo de entrada em um com o nome (por exemplo, name.in) e um com a idade (por exemplo, age.in), e mudar o read namee read agelinhas para name=$(cat name.in) e age=$(cat age.in)respectivamente.

Tomas Aschan
fonte
Eu tenho o seguinte script: vh = awk "NR == 3 {print; exit}" /var/www/test/test.txt com isso eu li a linha 3 do arquivo de texto chamado test.txt. Uma vez que recebo uma corda Eu quero usar essa seqüência como uma entrada para a criação de um diretório
user208413
11
Mude isso para vh=$(awk "NR==3 {print;exit}" /var/www/test.txt). Você terá a string salva na variável $vhe poderá usá-la da seguinte maneira: mkdir "/var/www/$vh"- isso criará uma pasta com o nome especificado dentro de / var / www.
Tomas Aschan 28/10
Eu fiz dessa maneira, mas ele ainda não pode criar a pasta :(
user208413
@ user208413: Que mensagens de erro você recebe? "Não funciona", infelizmente, não é uma descrição muito útil do problema ...
Tomas Aschan
3
name=$(<"$file") 

De man bash:1785, essa substituição de comando é equivalente, name=$(cat "$file")mas mais rápida.

inferno
fonte
2

Resposta curta:

name=`cat "$file"`
nedim
fonte
0

Se você quiser usar várias strings, poderá:

path="/foo/bar";
for p in `cat "$path"`;
do echo "$p" ....... (here you would pipe it where you need it) 

OU

Se você deseja que o usuário indique o arquivo

read -e "Specify path to variable(s): " path;
for p in 'cat "$path"';
do echo "$p" ............................
George
fonte
0
#! /bin/bash
#  (GPL3+) Alberto Salvia Novella (es20490446e)


variableInFile () {
    variable=${1}
    file=${2}

    source ${file}
    eval value=\$\{${variable}\}
    echo ${value}
}


variableInFile ${@}
Alberto Salvia Novella
fonte
0

Eu uso isso para obter uma única variável de um arquivo

GET_VAR=$(grep --color=never -Po "^${GET_VAR}=\K.*" "${FILE}" || true)

Quando GET_VARnão for encontrado ${FILE}, ficará em branco em vez de causar um erro, graças ao || true.

Ele usa o grep -Pque está no GNU grep, mas não o padrão em todo o grep no momento em que foi escrito.

Eric Nemchik
fonte
Isso não parece funcionar para mim. O $ inicial gera um erro por caractere ilegal
ginna 25/09