dg7*_*g72 5 bash array shell-script
我在 bash 中遇到了一些数组的问题。
A=( "127.0.0.1" "localhost" "aaa nnn cvcc" )
B=( "8.8.8.8" "dns" "bbb tttt rrrr")
for n in ${A} ${B} ; do
if ping -c3 ${n[0]};then
echo "${n[1]}"
for share in ${n[2]};do
echo $share
done
fi
done
Run Code Online (Sandbox Code Playgroud)
我想打印数组的第二个和第三个元素,但 for 循环在 ping 处停止。这样就可以工作了。
if ping -c3 ${A[0]};then
echo "${A[1]}"
for share in ${A[2]};do
echo $share
done
fi
Run Code Online (Sandbox Code Playgroud)
我敢肯定一定是一件非常愚蠢的事情,但它让我发疯......一些想法?提前谢谢了
您的循环实际上循环了Aand的第一个元素B,即${A[0]}and ${B[0]},这意味着${n[1]}and${n[2]}将是空字符串而${n[0]}与$n.
我可能会在bash(4.3 版或更高版本)中使用名称引用变量来执行此操作:
#!/bin/bash
A=( 127.0.0.1 localhost alpha beta gamma theta )
B=( 8.8.8.8 dns itsy bitsy 'spider man' )
for variable in A B; do
declare -n array="$variable"
if ping -c3 "${array[0]}" >/dev/null; then
printf '%s\n' "${array[1]}"
printf '\t%s\n' "${array[@]:2}"
fi
done
Run Code Online (Sandbox Code Playgroud)
我正在遍历变量名 A和B,而不是它们的内容。在循环中,我创建array了对由 命名的变量的名称引用$variable。Nowarray完全用作Aor 或B。
在if语句中,我不依赖shell来拆分第三个数组元素进行循环。相反,我在创建A和B数组时手动拆分它,并且我只是通过一次调用printf使用array数组中的偏移量来输出这些元素。为了便于阅读,我在每个元素前面输出了一个选项卡。
localhost
alpha
beta
gamma
theta
dns
itsy
bitsy
spider man
Run Code Online (Sandbox Code Playgroud)
该if声明也可以写为:
if ping -c3 "${array[0]}" >/dev/null; then
printf '%s: ' "${array[1]}"
( IFS=,; printf '%s\n' "${array[*]:2}" )
fi
Run Code Online (Sandbox Code Playgroud)
将其余的数组元素输出为冒号后的逗号分隔列表:
localhost: alpha,beta,gamma,theta
dns: itsy,bitsy,spider man
Run Code Online (Sandbox Code Playgroud)
注意:以上所有引用都不是偶然的。引用数组的扩展可确保每个元素都被单独引用。引用单个元素的扩展可确保 shell 不会在空格上拆分值(并且不会对拆分的单词进行文件名通配)。
也可以看看
您也可以在/bin/sh没有命名数组的情况下执行此操作。相反,我们使用位置参数列表来保存我们的数据,并用一个特殊词终止该列表的每个部分(我们使用END,这是我们选择的任意字符串)。然后我们循环遍历该列表并在执行过程中将元素移出它:
#!/bin/sh
set -- 127.0.0.1 localhost alpha beta gamma theta END \
8.8.8.8 dns itsy bitsy 'spider man' END
while [ "$#" -gt 0 ]; do
if ping -c 3 "$1" >/dev/null; then
printf '%s\n' "$2"
shift 2
while [ "$1" != END ]; do
printf '\t%s\n' "$1"
shift
done
else
while [ "$1" != END ]; do shift; done
fi
shift
done
Run Code Online (Sandbox Code Playgroud)
此答案并未直接解决您的问题,而是提供了该问题的替代解决方案。它不依赖于数组。
我将使用一个文件,而不是处理数组,IMO 的优点是将数据与程序分开。更容易编写和维护。
为此,用逗号,或其他字符将“共享”分开:
文件.txt
127.0.0.1 localhost aaa,nnn,cvcc
8.8.8.8 dns bbb,tttt,rrrr
failedip failed a,b,c
Run Code Online (Sandbox Code Playgroud)
剧本:
#!/bin/bash
# loop over the file's lines
while IFS=' ' read -r ip domain share; do
# a blank line to separate results at each loop
echo
# perform the `ping`, redirect to `/dev/null` if you don't need to print the output
if ping -c3 "$ip" &> /dev/null;then
echo "ping to $ip successful"
echo "domain: $domain"
# change the IFS to comma ',' in a subshell to parse the 'shares'
(IFS=,; printf "share: %s\n" $share)
else
# message if `ping` failed
echo "ping to $ip failed"
fi
done < file.txt
Run Code Online (Sandbox Code Playgroud)
输出:
ping to 127.0.0.1 successful
domain: localhost
share: aaa
share: nnn
share: cvcc
ping to 8.8.8.8 successful
domain: dns
share: bbb
share: tttt
share: rrrr
ping to failedip failed
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
463 次 |
| 最近记录: |