Jak odczytać zmienną z pliku?

68

Chcę wstawić do skryptu wartość (ciąg), którą odczytałbym z pliku tekstowego.

Na przykład zamiast:

echo "Enter your name"
read name

Chcę odczytać ciąg z innego pliku tekstowego, aby tłumacz mógł odczytać ciąg z pliku, a nie z danych wejściowych użytkownika.

użytkownik208413
źródło
1
Jak wygląda twój plik tekstowy? Czy cały plik 1 jest zmienny czy są KEY=VALUEparami? Rozwiązania są zupełnie inne (jeśli jest to drugie, zastosowanie ma odpowiedź Takkata, poprzednie Radu)
kiri
1
@CiroSantilli nie jest crosssposted, jeśli został opublikowany przez innego użytkownika, nie ma czegoś takiego jak „duplikat między witrynami”. Jedyne, czego należy unikać, to to samo pytanie zadawane przez tego samego użytkownika w różnych witrynach.
terdon

Odpowiedzi:

98

Aby odczytać zmienne z pliku, możemy użyć polecenia sourcelub ..

Załóżmy, że plik zawiera następujący wiersz

MYVARIABLE="Any string"

możemy następnie zaimportować tę zmienną za pomocą

#!/bin/bash

source <filename>
echo $MYVARIABLE
Takkat
źródło
16
Jednym z powodów, dla których możesz tego nie chcieć, jest to, że wszystko, co jest w <filename>środku, zostanie uruchomione w twojej powłoce, na przykład rm -rf /, co może być bardzo niebezpieczne.
Mark Ribau,
3
Późno na imprezę, ale nie, nie zasługuje na oznaczenie LUB jako odpowiedź. To źródło innego pliku źródłowego bash, który NIE jest tym, o co poprosił OP. Zapytał, jak wczytać zawartość PLIKU do zmiennej. NIE jak wykonać inny skrypt, który ustawia zmienną . Prawidłowa odpowiedź to jedna z poniższych. name = $ (cat „$ file”).
HörmannHH
2
OTOH, to jest odpowiedź na pytanie, które zadałem google i google sprowadziło mnie tutaj. Dziwne czasy, co?
Michael Terry,
1
Świetnie działa również w przypadku wielu zmiennych! Punkt @ MarkRibau jest zrozumiały, ale myślę, że jeśli poprawisz plik w innym skrypcie i po prostu będziesz musiał przekazać go w porządku i kontrolować.
madlymad
1
Możesz użyć, sedaby dodać localsłowo kluczowe i uczynić skrypt nieco bezpieczniejszym i nie zanieczyszczać globalnego zasięgu. Więc wewnątrz funkcji wykonaj, cat global_variables.sh | sed -e 's/^/local /' > local_variables.sha następnie użyj . ./local_variables.sh. Cokolwiek zaimportujesz do funkcji, będzie dostępne tylko w tej funkcji. Zauważ, że zakłada, że global_variables.shzawiera tylko jedną zmienną na linię.
Nux
55

Biorąc pod uwagę, że chcesz zachować całą zawartość pliku tekstowego w zmiennej, możesz użyć:

#!/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

Lub w czystej bash:

#!/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
źródło
Nie chcę wyświetlać zmiennej, chcę, aby ta zmienna została odczytana przez skrypt do dalszego przetwarzania. Próbowałem awk, który czyta wiersz po wierszu.
user208413,
1
Ok, usuń echo $name . Używam tego tylko do testu. Następnie możesz użyć $namezmiennej do dalszego przetwarzania w dowolnym miejscu skryptu.
Radu Rădeanu
Nie mogę go używać w dowolnym miejscu mojego skryptu, ponieważ skrypt nie zna wartości zmiennej. W naszym przypadku nazwa zmiennej.
user208413,
6
@ user208413 Wartością $namezmiennej jest łańcuch z pliku przypisany za pomocą cat $filepolecenia. Co nie jest jasne lub tak trudne do zrozumienia?
Radu Rădeanu
1
Używanie oddzielnej $filezmiennej jest zbędne, jeśli używasz jej tylko raz, aby załadować $namezmienną, po prostu użyjcat /path/to/file
kiri
11

Z poziomu skryptu możesz to zrobić:

read name < file_containing _the_answer

Możesz to zrobić nawet wiele razy, np. W pętli

while read LINE; do echo "$LINE"; done < file_containing_multiple_lines
thom
źródło
lub dla pliku z wieloma elementami w każdej linii. . . grep -v ^ # plik | podczas odczytu abc; wykonaj echo a = $ ab = $ bc = $ c; zrobić
gaoithe
7

Jednym z alternatywnych sposobów jest po prostu przekierowanie standardowego wejścia do pliku, w którym masz wszystkie dane wprowadzone przez użytkownika w kolejności, jakiej oczekuje program. Na przykład za pomocą programu (wywoływanego 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?"

i plik wejściowy (nazywany input.in)

Tomas
26

możesz uruchomić to z terminala na jeden z dwóch poniższych sposobów:

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

i byłoby to równoznaczne z uruchomieniem skryptu i ręcznym wprowadzeniem danych - wypisałby wiersz „Witaj Tomas. Masz 26 lat, prawda?”.

Jak Radu Rădeanu został już zasugerował , można użyć catwewnątrz skryptu do odczytania zawartości pliku w aVariable - w tym przypadku, trzeba każdy plik zawiera tylko jeden wiersz, tylko wartości, które chcesz dla tej konkretnej zmiennej. W powyższym przykładzie, można podzielić plik wejściowy do jednej z nazwą (powiedzmy name.in) i jednym z wiekiem (powiedzmy age.in) i zmienić read namei read agelinie name=$(cat name.in) i age=$(cat age.in)odpowiednio.

Tomas Aschan
źródło
Mam następujący skrypt: vh = awk "NR == 3 {print; exit}" /var/www/test/test.txt z tym czytam wiersz 3 z pliku tekstowego o nazwie test.txt. Gdy otrzymam ciąg, chcę go użyć jako danych wejściowych do utworzenia katalogu
user208413,
1
Zmień to na vh=$(awk "NR==3 {print;exit}" /var/www/test.txt). Będziesz wtedy zapisywać ciąg znaków w zmiennej $vh, dzięki czemu będziesz mógł go używać w następujący sposób: mkdir "/var/www/$vh"- utworzy to folder o określonej nazwie wewnątrz / var / www.
Tomas Aschan
Zrobiłem to w ten sposób, ale nadal nie mogę utworzyć folderu :(
user208413
@ user208413: Jakie komunikaty o błędach otrzymujesz? „To nie działa” to niestety niezbyt pomocny opis problemu ...
Tomas Aschan,
3
name=$(<"$file") 

Z man bash:1785tego podstawienie polecenia jest równoważne, name=$(cat "$file")ale szybsze.

cześć
źródło
2

Krótka odpowiedź:

name=`cat "$file"`
nedim
źródło
0

Jeśli chcesz użyć wielu ciągów, możesz użyć:

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

LUB

Jeśli chcesz, aby użytkownik wskazał plik

read -e "Specify path to variable(s): " path;
for p in 'cat "$path"';
do echo "$p" ............................
Jerzy
źródło
0
#! /bin/bash
#  (GPL3+) Alberto Salvia Novella (es20490446e)


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

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


variableInFile ${@}
Alberto Salvia Novella
źródło
0

Używam tego, aby uzyskać pojedynczą zmienną z pliku

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

Gdy GET_VARnie zostanie znaleziony ${FILE}, będzie pusty, zamiast powodować błąd dzięki || true.

Używa, grep -Pktóry jest w GNU grep, ale nie jest domyślny we wszystkich grep w momencie pisania tego.

Eric Nemchik
źródło
Wydaje mi się, że to nie działa. Początkowe $ zgłasza błąd dla nielegalnej postaci
ginna