bash + 通过 bash 脚本从文件中读取变量和值

bash + 通过 bash 脚本从文件中读取变量和值

我有以下文件变量和值

# more file.txt
export worker01="sdg sdh sdi sdj sdk"
export worker02="sdg sdh sdi sdj sdm"
export worker03="sdg sdh sdi sdj sdf"

我执行 source 来读取变量

# source file.txt

例子:

echo $worker01
sdg sdh sdi sdj sdk

到现在为止一切都很完美

但现在我想从文件中读取变量并通过简单的 bash 循环打印值我将读取第二个字段并尝试打印变量的值

#  for i in ` sed s'/=/ /g'  /tmp/file.txt | awk '{print $2}' `
   do  
   echo $i
   declare var="$i"
   echo $var
   done

但它只打印变量而不打印值

worker01
worker01
worker02
worker02
worker03
worker03

预期输出:

worker01
sdg sdh sdi sdj sdk
worker02
sdg sdh sdi sdj sdm
worker03
sdg sdh sdi sdj sdf

答案1

你有export worker01="sdg sdh sdi sdj sdk",那么你换成=一个空格就可以了export worker01 "sdg sdh sdi sdj sdk"。其中以空格分隔的字段为exportworker01"sdgsdh等。

最好拆分=并删除引号,因此只需使用 shell:

$ while IFS== read -r key val ; do
    val=${val%\"}; val=${val#\"}; key=${key#export };
    echo "$key = $val";
  done < vars
worker01 = sdg sdh sdi sdj sdk
worker02 = sdg sdh sdi sdj sdm
worker03 = sdg sdh sdi sdj sdf

key包含变量名、val值。当然,这实际上并没有解析输入,它只是删除双引号(如果恰好存在)。

答案2

awk独自的:

awk -F'"' '{print $2}' file.txt
# To print the variable name as well:
awk '{gsub(/[:=]/," "); gsub(/[:"]/,""); if ($1 = "export") {$1=""; print $0}}' file.txt

要循环它,您可以:

for i in "$(awk -F\" '{print $2}' file.txt)"; do
    var="$i"
    echo "$var"
done
my_array=($(awk -F\" '{print $2}' file.txt))
for element in "${my_var[@]}"; do
    another_var="$element"
    echo "$another_var"
done

如果您还想在循环中打印变量名称,您可以这样做:

#! /usr/bin/env bash -
while read -r line; do
    if [[ "$(awk '{print $1}' <<<"$line")" == 'export' ]]; then
        var_name="$(awk '{print $2}' <<<"$line" | awk -F'=' '{print $1}')"
        var_value="$(awk -F\" '{print $2}' <<<"$line")"
        echo -e "${var_name}\n${var_value}"
    else
        continue
    fi
done<file.txt

输出:

$ ./script.sh
worker01
sdg sdh sdi sdj sdk
worker02
sdg sdh sdi sdj sdm
worker03
sdg sdh sdi sdj sdf

答案3

首先,您可以使用 Perl 兼容的正则表达式通过 GNU grep 命令获取变量名称:

grep -oP 'export \K[^=]+' file.txt

然后,您可以使用以下命令将其输出读入 bash 数组:

mapfile -t variables < <(grep -oP 'export \K[^=]+' file.txt)

使用 bash 内置函数mapfile命令和一个流程替代

最后,迭代变量名称并使用间接参数扩展获取值:

for v in "${variables[@]}"; do 
    printf "varname=%s\tvalue=%s\n" "$v" "${!v}"
done
varname=worker01        value=sdg sdh sdi sdj sdk
varname=worker02        value=sdg sdh sdi sdj sdm
varname=worker03        value=sdg sdh sdi sdj sdf

答案4

你可以使用这个sed

sed -E 's/[^ ]* ([^=]*)="([^"]*)"/\1\n\2/' file.txt

或者这个 awk

awk -F '"|=' '{split($1,a," ");print a[2]"\n"$3}' file.txt

相关内容