我有一个文本文件,通常包含多行,我想用 while 循环“打印”这些行。该文件内的文本包含变量 - 我的问题是,这些变量的解释方式与包含存储在脚本内的变量的类似测试字符串不同。是否也可以从我的外部文件解释这些变量,或者我是否必须事先解析它们等?$LINE_INSIDE
和 和有什么区别$LINE_OUTSIDE
?我尝试了其他问题的一些建议,例如${!varialbe_name}
带有引号的不同结构,但到目前为止没有运气。
#!/bin/bash
# color.sh
BLUE='\033[1;34m'
NC='\033[0m' # No Color
LINE_INSIDE="${BLUE}Blue Text${NC}"
echo -e ${LINE_INSIDE}
while read LINE_OUTSIDE; do
echo -e ${LINE_OUTSIDE}
done < text_file
输出:
附加信息:我(确实)在我的输入文本文件中也有不应该执行的 shell 命令。仅应扩展变量。
答案1
将其写为以下形式可能更有意义:
BLUE=$'\033[1;34m'
NC=$'\033[0m' # No Color
eval "cat << EOF
$(<text_file)
EOF
"
比使用while read
循环(顺便说一句,这不是阅读行的正确语法)。
当然,这意味着其中的代码将被解释。例如,其中的 A$(reboot)
会导致重新启动,但这或多或少就是您所要求的。
这还假设text_file
不包含EOF
一行。
另一种方法将仅有的进行变量(环境变量)替换(例如不是命令替换)将使用 GNUgettext
的envsubst
:
BLUE=$'\033[1;34m'
NC=$'\033[0m' # No Color
export BLUE NC
envsubst < text_file
或者只扩展这两个变量:
BLUE=$'\033[1;34m'
NC=$'\033[0m' # No Color
export BLUE NC
envsubst '$BLUE$NC' < text_file
答案2
在较新的版本中bash
(从 4.4 版左右开始)还有另一种巧妙的方法可以间接扩展字符串中的变量,而不必完全执行eval
:@P
参数转换(=扩展如提示,包括但不限于变量替换)。
$ cat file.txt
${BLUE}hello blue${NORM}
$ BLUE=$'\e[34m'
$ NORM=$'\e[m'
$ while IFS= read -r line; do printf '%s\n' "${line@P}"; done < file.txt
hello blue