问题描述
variables.conf的内容
VAR1=/destination1 # comment
VAR2=/destination2 # comment
脚本
VAR1=./variables.conf
for file in $(cat $VAR1 | sed 's/^/$/');
do
echo "${file%=*}"
done
输出
$VAR1
$VAR2
我需要这样的输出,但无法弄清楚
$VAR1 # comment
$VAR2 # comment
解决方法
根据定义,注释在脚本外是不可见的,它们不能导出或使用(嗯,有点,但这是另一回事)。
可以通过创建带有预期注释的两个字符串变量,然后使用echo命令来处理它们,来实现您的意思,例如:
#! /bin/bash
comment1="# Hey-ho"
comment2="# Let's go"
VAR1=/destination1
VAR2=/destination2
echo -e "$VAR1 $comment1\n$VAR2 $comment2" #why waste a good echo ;)
这应该可以完成工作。您可以顺便说一句跳过de'#',因为这将明显显示为字符串,但只是为了保持语法。当然,我的最后推荐不会被印刷。
当然,您将不得不重复工作,但是正如我所说,注释是注释,除非您正在阅读代码,否则它们不打算显示。
,我为您编写了一个小功能。我希望var不会被定义两次,否则您必须确保grep
仅获得第一个。另外,这在真正的旧bash版本上不起作用,我使用版本5.0.3
。
#! /bin/bash
SCRIPTNAME=$0
VAR1=/destination1 # comment 1
VAR2=/destination2 # comment 2
function print_comment {
local var_name=$1
local -n var_content=$1
local comment=""
comment=$(grep -E "^${var_name}=.*" $SCRIPTNAME | sed -r 's/^[^#].*(#.*)$/\1/')
echo "$var_content $comment"
}
print_comment VAR1
print_comment VAR2
exit 0
这将输出:
$ ./tst.sh
/destination1 # comment 1
/destination2 # comment 2
,
在Bash 4+关联数组中以映射变量名称作为键并以注释作为值的方式:
#!/usr/bin/env bash
varfile='variables.conf'
# shellcheck source=./variables.conf
. "$varfile"
# shellcheck disable=SC2155 # safe assignement
declare -A comments="($(
while IFS=$'\37' read -r k v; do
printf '[%q]=%q\n' "$k" "$v"
done< <(sed 's/^\([^=]*\)=[^#]\+#\ \?\(.*\)/\1\x1F\2/' "$varfile")
))"
for varname in "${!comments[@]}"; do
comment="${comments[$varname]}"
value="${!varname}"
printf '%-20s %-30s %s\n' "$varname" "$value" "$comment"
done
,
我不知道为什么人们会如此复杂化。只需逐行循环并以提取名称的方式提取注释:
VAR1=./variables.conf
sed 's/^/$/' "$VAR1" | while read -r file
do
echo "${file%=*} #${file##*#}"
done
或首先使用sed
完成所有操作:
sed -e 's/^/$/; s/=[^#]*/ /' "$VAR1"