如何从文件读取变量?


68

我想在脚本中插入将从文本文件中读取的值(字符串)。

例如,代替:

echo "Enter your name"
read name

我想从另一个文本文件中读取字符串,因此解释器应从文件而不是用户输入中读取字符串。


1
您的文本文件是什么样的?整个文件是1个变量还是KEY=VALUE成对?解决方案是完全不同的(如果是后者,则应使用Takkat的答案,而应使用前Radu的方法)
kiri

1
@CiroSantilli,如果它是由其他用户发布的,则不会被交叉发布,没有“跨站点重复”之类的东西。唯一应避免的是同一用户在不同站点上提出的同一问题。
terdon

Answers:


98

要从文件中读取变量,我们可以使用sourceor .命令。

假设文件包含以下行

MYVARIABLE="Any string"

然后我们可以使用导入该变量

#!/bin/bash

source <filename>
echo $MYVARIABLE

16
您可能不想这样做的原因之一是因为其中的任何内容都<filename>将在您的shell中运行,例如rm -rf /,这可能非常危险。
Mark Ribau 2015年

3
晚会晚了,但是,不,它不应该被标记为答案。这将获得另一个bash源文件,这不是OP所要求的。他询问如何将FILE的内容读入变量。不是如何执行另一个设置变量的脚本。正确的答案是下面的答案。name = $(cat“ $ file”)。
HörmannHH

2
太太了,这是我问Google并将Google带到这里的问题的答案。奇怪的时候,是吗?
Michael Terry

1
Great也适用于多个变量!@MarkRibau的要点是可以理解的,但是我猜想,如果您使用其他脚本纠正文件,而只需要通过它的良好控制即可。
madlymad '17

1
您可以使用sedadd 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逐行读取。
2013年

1
好的,删除echo $name 。我仅将其用于测试。接下来,您可以使用$name变量在脚本中的任何位置进行进一步处理。
RaduRădeanu13年

我不能在脚本的任何地方使用它,因为脚本不知道变量的值。在我们的例子中,变量名。
2013年

6
@ user208413 $name变量的值是使用cat $file命令分配的文件中的字符串。什么不清楚或很难理解?
RaduRădeanu13年

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; 做回声a = $ ab = $ bc = $ c; 完成
gaoithe 2015年

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

这相当于只运行脚本并手动输入数据-它会打印“ Hello Tomas。您今年26岁,对吧?”。

正如RaduRădeanu建议的那样,您可以cat在脚本内部使用将文件的内容读取到变量中-在这种情况下,您需要每个文件仅包含一行,并且只包含该特定变量所需的值。在上面的例子中,你输入文件分割成一个名为(比如说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,我从名为test.txt的文本文件中读取了第3行。一旦我得到一个字符串,我想使用该字符串作为创建目录的输入
user208413

1
将其更改为vh=$(awk "NR==3 {print;exit}" /var/www/test.txt)。然后,您将字符串保存在variable中$vh,因此可以像这样使用它:mkdir "/var/www/$vh"-这将在/ var / www中创建一个具有指定名称的文件夹。
Tomas Aschan

我已经这样做了,但是它仍然无法创建文件夹:(
user208413

@ user208413:您得到什么错误消息?不幸的是,“它不起作用”不是一个非常有用的问题描述...
Tomas Aschan


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
#! /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 -P在编写此代码时,它使用的是GNU grep中的哪个,但不是所有grep中的默认值。


这似乎对我不起作用。最初的$会因非法字符错误
金纳
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.