如何在 Bash 中创建用于评估的变量
how to create a variable for evaluation in Bash
我的 CSV 文件是这样写的:
Source,Target,Database,Table,Is_deletable,Action
DBServer1,DBServer2,DB,TBL1,true,Add
DBServer2,DBServer1,DB,TBL2,true,Add
我有 shell 执行此操作的脚本:
while IFS=, read -r source target database table is_deletable action; do
echo "Building pipeline for ${database}.${table}";
total=$((total+1))
Shost="server1.myorganization.com"
Thost="server2.myorganization.com"
我需要 Shost 看起来像这样:
Shost = ${'the value of the source column'}
Thost = ${'the value of the target column'}
如何设置它以根据列数据的值动态评估我需要的变量。
例如:
Shost=${DBServer1}
Thost=${DBServer2}
然后在下一个循环中:
Shost=${DBServer2}
Thost=${DBServer1}
谢谢!
像这样的东西应该适合你:
DBServer1='server1.myorganization.com'
DBServer2='server2.myorganization.com'
while IFS=, read -r source target database table is_deletable action; do
[[ $source = "Source" ]] && continue
((total++))
Shost="${!source}"
Thost="${!target}"
# check variables Shost Thost total
declare -p Shost Thost total
done < file.csv
declare -- Shost="server1.myorganization.com"
declare -- Thost="server2.myorganization.com"
declare -- total="1"
declare -- Shost="server2.myorganization.com"
declare -- Thost="server1.myorganization.com"
declare -- total="2"
在 Bash 中——但不一定在其他 shell 中——你可以间接地引用一个变量,就像你想做的那样:
$ DBServer1=db1.my.com
$ source=DBServer1
$ echo ${source}
DBServer1
$ echo ${!source}
db1.my.com
正如 Bash 手册所说 (ref):
If [in a parameter expansion of the
form ${parameter}
] the first character of parameter
is an exclamation point (!), and parameter
is
not a nameref
, it introduces a level of variable indirection. Bash
uses the value of the variable formed from the rest of parameter
as
the name of the variable; this variable is then expanded and that
value is used in the rest of the substitution, rather than the
value of parameter itself.
将其应用于您的示例代码和数据,我们得到
DBServer1=server1.myorganization.com
DBServer2=server2.myorganization.com
# ...
while IFS=, read -r source target database table is_deletable action; do
echo "Building pipeline for ${database}.${table}";
total=$((total+1))
Shost="${!source}"
Thost="${!target}"
我们也可以使用关联数组来解决这个问题:
declare -A servers=(
[DBServer1]='server1.myorganization.com'
[DBServer2]='server2.myorganization.com'
)
{
read header
while IFS=, read -r source target database table is_deletable action; do
Shost=${servers[$source]}
Thost=${servers[$target]}
...
done
} < file.csv
我的 CSV 文件是这样写的:
Source,Target,Database,Table,Is_deletable,Action
DBServer1,DBServer2,DB,TBL1,true,Add
DBServer2,DBServer1,DB,TBL2,true,Add
我有 shell 执行此操作的脚本:
while IFS=, read -r source target database table is_deletable action; do
echo "Building pipeline for ${database}.${table}";
total=$((total+1))
Shost="server1.myorganization.com"
Thost="server2.myorganization.com"
我需要 Shost 看起来像这样:
Shost = ${'the value of the source column'}
Thost = ${'the value of the target column'}
如何设置它以根据列数据的值动态评估我需要的变量。
例如:
Shost=${DBServer1}
Thost=${DBServer2}
然后在下一个循环中:
Shost=${DBServer2}
Thost=${DBServer1}
谢谢!
像这样的东西应该适合你:
DBServer1='server1.myorganization.com'
DBServer2='server2.myorganization.com'
while IFS=, read -r source target database table is_deletable action; do
[[ $source = "Source" ]] && continue
((total++))
Shost="${!source}"
Thost="${!target}"
# check variables Shost Thost total
declare -p Shost Thost total
done < file.csv
declare -- Shost="server1.myorganization.com"
declare -- Thost="server2.myorganization.com"
declare -- total="1"
declare -- Shost="server2.myorganization.com"
declare -- Thost="server1.myorganization.com"
declare -- total="2"
在 Bash 中——但不一定在其他 shell 中——你可以间接地引用一个变量,就像你想做的那样:
$ DBServer1=db1.my.com
$ source=DBServer1
$ echo ${source}
DBServer1
$ echo ${!source}
db1.my.com
正如 Bash 手册所说 (ref):
If [in a parameter expansion of the form
${parameter}
] the first character ofparameter
is an exclamation point (!), andparameter
is not anameref
, it introduces a level of variable indirection. Bash uses the value of the variable formed from the rest ofparameter
as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself.
将其应用于您的示例代码和数据,我们得到
DBServer1=server1.myorganization.com
DBServer2=server2.myorganization.com
# ...
while IFS=, read -r source target database table is_deletable action; do
echo "Building pipeline for ${database}.${table}";
total=$((total+1))
Shost="${!source}"
Thost="${!target}"
我们也可以使用关联数组来解决这个问题:
declare -A servers=(
[DBServer1]='server1.myorganization.com'
[DBServer2]='server2.myorganization.com'
)
{
read header
while IFS=, read -r source target database table is_deletable action; do
Shost=${servers[$source]}
Thost=${servers[$target]}
...
done
} < file.csv