Как мне прочитать переменную из файла?

68

Я хочу вставить в мой скрипт значение (строку), которое я бы прочитал из текстового файла.

Например, вместо:

echo "Enter your name"
read name

Я хочу прочитать строку из другого текстового файла, поэтому интерпретатор должен читать строку из файла, а не пользовательский ввод.

user208413
источник
1
Как выглядит ваш текстовый файл? Является ли весь файл 1 переменной или это KEY=VALUEпары? Решения совершенно разные (если это последнее, то ответ Такката применим, а ответ прежнего Раду)
Кири
1
@CiroSantilli не является перекрестным, если он был опубликован другим пользователем, не существует такой вещи, как «дубликат между сайтами». Единственное, чего следует избегать, это один и тот же вопрос, задаваемый одним и тем же пользователем на разных сайтах.
Тердон

Ответы:

98

Для чтения переменных из файла мы можем использовать команду sourceor ..

Предположим, что файл содержит следующую строку

MYVARIABLE="Any string"

затем мы можем импортировать эту переменную, используя

#!/bin/bash

source <filename>
echo $MYVARIABLE
Takkat
источник
17
Одна из причин, по которой вы, возможно, не захотите делать это таким образом, заключается в том, что все, что находится внутри, <filename>будет запущено в вашей оболочке, например rm -rf /, что может быть очень опасным.
Марк Рибау
4
Поздно на вечеринке, но, нет, это не заслуживает того, чтобы быть отмеченным ИЛИ как ответ. Это создает другой исходный файл bash, который НЕ является тем, что запрашивал OP. Он спросил, как прочитать содержимое ФАЙЛА в переменную. НЕ как выполнить другой скрипт, который устанавливает переменную . Правильный ответ приведен ниже. name = $ (cat "$ file").
HörmannHH
2
ОТО, это ответ на вопрос, который я задал Google, и Google привел меня сюда. Странные времена, а?
Майкл Терри
1
Отлично работает и для нескольких переменных! Точка @MarkRibau понятна, но я думаю, что если вы исправите файл в другом скрипте и просто должны передать его в порядке и контролируемо.
madlymad
1
Вы можете использовать, sedчтобы добавить localключевое слово и сделать сценарий немного более безопасным и не разрушить вашу глобальную область. Так что внутри функции, cat global_variables.sh | sed -e 's/^/local /' > local_variables.shа затем использовать . ./local_variables.sh. Все, что вы импортируете в функцию, будет доступно только в этой функции. Обратите внимание, что предполагается, что global_variables.shсодержит только одну переменную на строку.
Nux
55

Учитывая, что вы хотите, чтобы все содержимое вашего текстового файла было сохранено в вашей переменной, вы можете использовать:

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

Или в чистом виде:

#!/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
Раду Рэдяну
источник
Я не хочу отображать переменную, я хочу, чтобы эта переменная была прочитана скриптом для дальнейшей обработки. Я пробовал awk, который читает построчно.
user208413
1
Ок, удали echo $name . Я использую это только для теста. Далее вы можете использовать $nameпеременную для дальнейшей обработки в любом месте вашего скрипта.
Раду Рэдяну
Я не могу использовать его в любом месте моего сценария, потому что сценарий не знает значение переменной. В нашем случае имя переменной.
user208413
6
@ user208413 Значением $nameпеременной является строка из вашего файла, назначенная с помощью cat $fileкоманды. Что не понятно или так сложно понять?
Раду Рэдяну
1
Излишне использовать отдельную $fileпеременную, если вы используете ее только один раз для загрузки $nameпеременной, просто используйтеcat /path/to/file
kiri
11

Из вашего скрипта вы можете сделать это:

read name < file_containing _the_answer

Вы даже можете сделать это несколько раз, например, в цикле

while read LINE; do echo "$LINE"; done < file_containing_multiple_lines
Thom
источник
или для файла с несколькими элементами в каждой строке. , , grep -v ^ # file | при чтении abc; сделайте эхо a = $ ab = $ bc = $ c; сделано
gaoithe
Это читает всю строку файла, а не переменную, объявленную в файле.
Бельведер
7

Один из альтернативных способов сделать это - просто перенаправить стандартный ввод в ваш файл, где у вас есть весь пользовательский ввод в порядке, ожидаемом программой. Например, с помощью программы (называется 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?"

и входной файл (называется input.in)

Tomas
26

Вы можете запустить это из терминала одним из следующих двух способов:

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

и это было бы равносильно простому запуску сценария и вводу данных вручную - это вывело бы строку «Здравствуйте, Томас. Вам 26 лет, верно?».

Как Radu Rădeanu имеет уже предложил , вы можете использовать catвнутри сценария , чтобы прочитать содержимое файла в avariable - в этом случае, вам нужно каждый файл содержит только одну строку, только значение , которое требуется для этой конкретной переменной. В приведенном выше примере, вы бы разделить входной файл на один с именем (скажем, name.in) и один с возрастом (скажем, age.in), а также изменить read nameи read ageстроку name=$(cat name.in) и age=$(cat age.in)соответственно.

Томас Ашан
источник
У меня есть следующий скрипт: vh = awk "NR == 3 {print; exit}" /var/www/test/test.txt с этим я читаю строку 3 из текстового файла с именем test.txt. Как только я получу строку, я хочу использовать эту строку в качестве входных данных для создания каталога
user208413
1
Измени это на vh=$(awk "NR==3 {print;exit}" /var/www/test.txt). Затем строка будет сохранена в переменной $vh, поэтому вы можете использовать ее следующим образом: mkdir "/var/www/$vh"- это создаст папку с указанным именем внутри / var / www.
Томас Ашан
Я сделал это так, но он все еще не может создать папку :(
user208413
@ user208413: Какие сообщения об ошибках вы получаете? «Это не работает», к сожалению, не очень полезное описание проблемы ...
Томас Ашан
3
name=$(<"$file") 

От man bash:1785, эта подстановка команд эквивалентна, name=$(cat "$file")но быстрее.

hellork
источник
0

Если вы хотите использовать несколько строк, вы можете использовать:

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

ИЛИ ЖЕ

Если вы хотите, чтобы пользователь указал файл

read -e "Specify path to variable(s): " path;
for p in 'cat "$path"';
do echo "$p" ............................
Джордж
источник
0
#! /bin/bash
#  (GPL3+) Alberto Salvia Novella (es20490446e)


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

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


variableInFile ${@}
Альберто Сальвия Новелла
источник
0

Я использую это, чтобы получить одну переменную из файла

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

Когда GET_VARон не найден, ${FILE}он будет пустым, а не вызовет ошибку благодаря || true.

Он использует grep -PGNU grep, но не используется по умолчанию во всех grep на момент написания этого.

Эрик Немчик
источник
Это не похоже на работу для меня. Первоначальный $ выдает ошибку за незаконный характер
Ginna