数据驱动 shell 编程?请提出建议
Datadriven shell programming? Suggestions, please
我想将我的 shell 脚本转换为使用数据驱动方法。但是由于在任何 shell 中都没有 "tables" 类型值(据我所知),有什么建议的替代方法可以做到这一点?
我正在寻找的解决方案可以让人们做如下事情:
animals = [['horse', 300 'brown'],
['cat', 3, 'black'],
['elephant', 3000, 'grey'],
['mouse', 0.3, 'grey']]
for a in animals ; do
echo "A typical $a[1] is $a[3] and weighs about $a[2] kilograms."
done
更准确地说,我想尝试一些命令,看看其中一个是否可用,然后向它发送参数:
commands = [['c1', '-m', '-i'],
['c2', '-message', '-icon'],
['c3', '/m', '/i']]
for c in commands ; do
if exists c[1] ; then
command = c[1]
message_option = c[2]
icon_option = c[3]
break;
fi
done
$command $message_option "message" $icon_option icon
试试这个?
cat file
'horse', 300, 'brown'
'cat', 3, 'black'
'elephant', 3000, 'grey'
'mouse', 0.3, 'grey'
for i in {1..4} ;
do
animal=$(awk -F, -v var="$i" 'NR== var {print }' file)
weight=$(awk -F, -v var="$i" 'NR== var {print }' file)
colour=$(awk -F, -v var="$i" 'NR== var {print }' file)
echo "A typical "$animal" is "$colour" and weighs about "$weight" kilos."
done
输出-
A typical 'horse' is 'brown' and weighs about 300 kilos.
A typical 'cat' is 'black' and weighs about 3 kilos.
A typical 'elephant' is 'grey' and weighs about 3000 kilos.
A typical 'mouse' is 'grey' and weighs about 0.3 kilos.
您可以根据需要在 bash
中定义和使用 associative-arrays。
#!/bin/bash
# declaring the Associative array
declare -a animals
animals[0]="'horse':300:'brown'"
animals[1]="'cat':3:'black'"
animals[2]="'elephant':3000:'grey'"
animals[3]="'mouse':0.3:'grey'"
for animal in "${animals[@]}"
do
myArray=(${animal//:/ })
printf "A typical "${myArray[0]}" is "${myArray[2]}" and weighs about "${myArray[1]}" kilograms.\n"
done
上面唯一棘手的部分是 parameter-expansion 类型
${parameter/pattern/string}
The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string.
If pattern begins with ‘/’, all matches of pattern are replaced with string. Normally only the first match is replaced.
因此,理想情况下,字符串 'horse':300:'brown'
被拆分为单独的元素并存储在数组 myArray
中,该数组稍后用于访问 C 样式循环中的单独元素。
不需要任何 bashisms。这可以通过 while read
循环读取的 here-document 巧妙地解决:
#!/bin/sh
while read animal weigth colour; do
printf '%s\n' "A typical $animal is $colour and weighs about $weight kilos."
done << EOF
horse 300 brown
cat 3 black
elephant 3000 grey
mouse 0.3 grey
EOF
观察这是如何按名称引用元素的,而不是使用 1、2、3 的神秘索引。它没有 fork/exec 任何外部命令,并且击败了另一个答案中看到的循环体中的 3 个 awk放下手。
我想将我的 shell 脚本转换为使用数据驱动方法。但是由于在任何 shell 中都没有 "tables" 类型值(据我所知),有什么建议的替代方法可以做到这一点?
我正在寻找的解决方案可以让人们做如下事情:
animals = [['horse', 300 'brown'],
['cat', 3, 'black'],
['elephant', 3000, 'grey'],
['mouse', 0.3, 'grey']]
for a in animals ; do
echo "A typical $a[1] is $a[3] and weighs about $a[2] kilograms."
done
更准确地说,我想尝试一些命令,看看其中一个是否可用,然后向它发送参数:
commands = [['c1', '-m', '-i'],
['c2', '-message', '-icon'],
['c3', '/m', '/i']]
for c in commands ; do
if exists c[1] ; then
command = c[1]
message_option = c[2]
icon_option = c[3]
break;
fi
done
$command $message_option "message" $icon_option icon
试试这个?
cat file
'horse', 300, 'brown'
'cat', 3, 'black'
'elephant', 3000, 'grey'
'mouse', 0.3, 'grey'
for i in {1..4} ;
do
animal=$(awk -F, -v var="$i" 'NR== var {print }' file)
weight=$(awk -F, -v var="$i" 'NR== var {print }' file)
colour=$(awk -F, -v var="$i" 'NR== var {print }' file)
echo "A typical "$animal" is "$colour" and weighs about "$weight" kilos."
done
输出-
A typical 'horse' is 'brown' and weighs about 300 kilos.
A typical 'cat' is 'black' and weighs about 3 kilos.
A typical 'elephant' is 'grey' and weighs about 3000 kilos.
A typical 'mouse' is 'grey' and weighs about 0.3 kilos.
您可以根据需要在 bash
中定义和使用 associative-arrays。
#!/bin/bash
# declaring the Associative array
declare -a animals
animals[0]="'horse':300:'brown'"
animals[1]="'cat':3:'black'"
animals[2]="'elephant':3000:'grey'"
animals[3]="'mouse':0.3:'grey'"
for animal in "${animals[@]}"
do
myArray=(${animal//:/ })
printf "A typical "${myArray[0]}" is "${myArray[2]}" and weighs about "${myArray[1]}" kilograms.\n"
done
上面唯一棘手的部分是 parameter-expansion 类型
${parameter/pattern/string}
The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string.
If pattern begins with ‘/’, all matches of pattern are replaced with string. Normally only the first match is replaced.
因此,理想情况下,字符串 'horse':300:'brown'
被拆分为单独的元素并存储在数组 myArray
中,该数组稍后用于访问 C 样式循环中的单独元素。
不需要任何 bashisms。这可以通过 while read
循环读取的 here-document 巧妙地解决:
#!/bin/sh
while read animal weigth colour; do
printf '%s\n' "A typical $animal is $colour and weighs about $weight kilos."
done << EOF
horse 300 brown
cat 3 black
elephant 3000 grey
mouse 0.3 grey
EOF
观察这是如何按名称引用元素的,而不是使用 1、2、3 的神秘索引。它没有 fork/exec 任何外部命令,并且击败了另一个答案中看到的循环体中的 3 个 awk放下手。