Як прочитати змінну з файлу?


68

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

Наприклад, замість:

echo "Enter your name"
read name

Я хочу прочитати рядок з іншого текстового файлу, щоб перекладач повинен прочитати рядок з файлу, а не введення користувача.


1
Як виглядає ваш текстовий файл? Чи є весь файл 1 змінним чи вони KEY=VALUEпарами? Рішення зовсім інші (якщо це останнє, застосовується відповідь Такката, колишня Раду)
kiri

1
@CiroSantilli це не перехресне повідомлення, якщо його опублікував інший користувач, немає такого поняття, як "дублікат між сайтом". Єдине, чого слід уникати - це те саме запитання, яке задає той самий користувач на різних сайтах.
тердон

Відповіді:


98

Для читання змінних з файлу ми можемо використовувати команду sourceабо ..

Припустимо, що файл містить такий рядок

MYVARIABLE="Any string"

ми можемо імпортувати цю змінну за допомогою

#!/bin/bash

source <filename>
echo $MYVARIABLE

16
Однією з причин, чому ви можете не хотіти цього робити, є те, що все, що є, <filename>буде працювати у вашій оболонці, наприклад rm -rf /, що може бути дуже небезпечно.
Марк Рібау

3
Пізно до партії, але, ні, вона не заслуговує на те, щоб її відзначити АБО як відповідь. Це створює ще один вихідний файл bash, який НЕ є тим, про що вимагала ОП. Він запитав, як прочитати вміст файлу в змінну. НЕ як виконати інший скрипт, який встановлює змінну . Правильна відповідь - одна нижче. name = $ (cat "$ file").
HörmannHH

2
ОТО, це відповідь на питання, яке я задав google і google привів мене сюди. Дивні часи, так?
Майкл Террі

1
Чудово також працює для декількох змінних! Точка @MarkRibau зрозуміла, але, мабуть, якщо ви виправите файл в іншому скрипті, вам просто доведеться передати його надто чітко і під контролем.
madlymad

1
Ви можете використовувати sedдля додавання localключових слів і зробити сценарій трохи безпечнішим, а не випустити глобальну область застосування. Тому всередині функції aa виконайте, 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, який читає рядок за рядком.
користувач208413

1
Добре, видалити echo $name . Я використовую його просто для тесту. Далі ви можете використовувати $nameзмінну для подальшої обробки в будь-якому місці вашого сценарію.
Radu Rădeanu

Я не можу використовувати його де-небудь, це мій сценарій, оскільки сценарій dhe не знає значення змінної. У нашому випадку ім'я змінної.
користувач208413

6
@ user208413 Значенням $nameзмінної є рядок з вашого файлу, призначений за допомогою cat $fileкоманди. Що незрозуміло чи так важко зрозуміти?
Radu Rădeanu

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

або для файлу з декількома елементами в кожному рядку. . . grep -v ^ # файл | під час читання abc; do echo 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")але швидша.



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

Я використовую це для отримання єдиної змінної з файлу

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

Якщо GET_VARйого не знайти, ${FILE}він буде порожнім, а не викликає помилку завдяки || true.

Він використовує, grep -Pщо є в GNU grep, але не є типовим для всіх grep на момент написання цього.


Це, здається, не працює для мене. Початкові $ кидає помилку за незаконний персонаж
ginna
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.