Arrays Bash从配置文件解析数组
我需要为文件中的每个“部分”设置一个数组,其中包含:Arrays Bash从配置文件解析数组,arrays,linux,bash,parsing,configuration-files,Arrays,Linux,Bash,Parsing,Configuration Files,我需要为文件中的每个“部分”设置一个数组,其中包含: [array0] value1=asdf value2=jkl [array1] value1=1234 value2=5678 我希望能够像这样检索这些值: echo ${array0[value1]} echo ${array0[value2]} echo ${array1[value1]} echo ${array1[value2]} 你有没有想过如何做到这一点?(解释将是一种奖励) 我已经读过这些书,但没有一本能完全满足我的要
[array0]
value1=asdf
value2=jkl
[array1]
value1=1234
value2=5678
我希望能够像这样检索这些值:
echo ${array0[value1]}
echo ${array0[value2]}
echo ${array1[value1]}
echo ${array1[value2]}
你有没有想过如何做到这一点?(解释将是一种奖励)
我已经读过这些书,但没有一本能完全满足我的要求
您可以使用
declare-a=(值1值2值3)
然后你可以像这样使用它们
echo${[index]}
编辑:
好的,从配置文件构造数组。我建议您为要创建的每个阵列使用不同的文件
下面是步骤
1.config文件(创建一个文件并将值放入其中)
100
200
300
2.脚本文件(从文件中读取值并准备数组)
数组=()
#设置阵列
而IFS=$'\n'读取-a配置
做
数组+=(${config})
完成<文件名
#访问值
echo${array[0]}
echo${array[1]}
IFS表示分隔符-a指定要提取到的数组名,以便您可以在while循环中访问它们。我正要出去,但我认为您可以执行类似的操作(未经测试),可能会有聪明的人,如@anubhava,将其拾取并完成
eval $(gawk -F= '/^\[/{name=gensub(/\[|\]/,"","g");x=0} /=/{print "name[",x++,"]=",$2," "}' config)
基本上,当它看到一行以“[
”开头时,它会在变量name
中提取数组名,并用gensub()
去掉方括号。然后,当它看到一行中有“=
”时,它会输出数组名和一个递增的索引“x
”,以便eval
提取
必须冲刺-查看示例,了解
stat-s
Oneeval
-免费,100%纯Bash可能性:
#!/bin/bash
die() {
printf >&2 "%s\n" "$@"
exit 1
}
aryname=''
linenb=0
while read line; do
((++linenb))
if [[ $line =~ ^[[:space:]]*$ ]]; then
continue
elif [[ $line =~ ^\[([[:alpha:]][[:alnum:]]*)\]$ ]]; then
aryname=${BASH_REMATCH[1]}
declare -A $aryname
elif [[ $line =~ ^([^=]+)=(.*)$ ]]; then
[[ -n aryname ]] || die "*** Error line $linenb: no array name defined"
printf -v ${aryname}["${BASH_REMATCH[1]}"] "%s" "${BASH_REMATCH[2]}"
else
die "*** Error line $linenb: $line"
fi
done
按标准输入读取。如果要从文件读取,请通过以下方式更改done
:
done < "filename"
允许使用bash v4,使用关联数组,将配置文件中的属性存储为实际bash变量:
$ while read line; do
if [[ $line =~ ^"["(.+)"]"$ ]]; then
arrname=${BASH_REMATCH[1]}
declare -A $arrname
elif [[ $line =~ ^([_[:alpha:]][_[:alnum:]]*)"="(.*) ]]; then
declare ${arrname}[${BASH_REMATCH[1]}]="${BASH_REMATCH[2]}"
fi
done < config.conf
$ echo ${array0[value1]}
asdf
$ echo ${array1[value2]}
5678
$ for i in "${!array0[@]}"; do echo "$i => ${array0[$i]}"; done
value1 => asdf
value2 => jkl
$ for i in "${!array1[@]}"; do echo "$i => ${array1[$i]}"; done
value1 => 1234
value2 => 5678
$whilereadline;do
如果[[$line=~^“[”(.+)“]“$]”;则
arrname=${BASH_重新匹配[1]}
declare-A$arrname
elif[[$line=~^([[u[:alpha:][[u[:alnum:]]*)“=”(.*)”;然后
声明${arrname}[${BASH_REMATCH[1]}]=“${BASH_REMATCH[2]}”
fi
完成${array0[$i]}”已完成
值1=>asdf
值2=>jkl
$表示“${!array1[@]}”中的i,执行echo“$i=>${array1[$i]}”已完成
值1=>1234
值2=>5678
你必须使用Bash吗?这类事情对于Ruby、YAML、Python、JSON、Lua或其他一些事情来说都是微不足道的。我认为最好使用Bash来完成我的工作。我需要使用screen命令和其他相关的东西。关于你实际要做的事情的更多细节可能会有帮助。我了解如何声明和使用数组,但我的问题是从文件中解析数组。我喜欢这个答案,但我发现使用array0[value1]而不是array0[0]更方便。它更适合我的需要。(更新的问题)@AJFerguson很高兴读到这篇文章!事实上,我不得不以一种非常不自然的方式调整内容以满足您的原始需求!让我编辑答案以满足您的新(更自然)需求。@AJFerguson更改(简化)以适应您的新需求。
done < "filename"
space and funnŷ sÿmbòl=value that will have an equal sign: look = it's funny
$ while read line; do
if [[ $line =~ ^"["(.+)"]"$ ]]; then
arrname=${BASH_REMATCH[1]}
declare -A $arrname
elif [[ $line =~ ^([_[:alpha:]][_[:alnum:]]*)"="(.*) ]]; then
declare ${arrname}[${BASH_REMATCH[1]}]="${BASH_REMATCH[2]}"
fi
done < config.conf
$ echo ${array0[value1]}
asdf
$ echo ${array1[value2]}
5678
$ for i in "${!array0[@]}"; do echo "$i => ${array0[$i]}"; done
value1 => asdf
value2 => jkl
$ for i in "${!array1[@]}"; do echo "$i => ${array1[$i]}"; done
value1 => 1234
value2 => 5678