我正在尝试创建一个case语句,并且我使用以下通配符来创建参数之间的差异:
这是针对单个IP:
case $1 in
//the argument is a single IP
*.*.*.0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31`|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255 )
....`
//the argument is a IP range
`*.*.*.*-*.*.*.* )
....`
即便如此,似乎它不起作用,我做错了什么?
感谢,
答案 0 :(得分:4)
对于单个IP,您已定义了这些替代方案
*.*.*.0
1
2
和不
*.*.*.0
*.*.*.1
*.*.*.2
此处使用的模式类型称为glob
。
如果你真的想拼出来,你必须说
*.*.*.0|*.*.*.1|*.*.*.2|...)
如果您想拥有最多三个字符,也可以指定此字符
*.*.*.?|*.*.*.??|*.*.*.???)
或最多三位数
*.*.*.[0-9]|*.*.*.[0-9][0-9]|*.*.*.[0-9][0-9][0-9])
但是这允许例如127.1.3.843
也是如此。
如果你有
case "$arg" in
single-IP) ... ;;
IP-range) ... ;;
esac
它将首先测试始终匹配的单IP。要匹配范围,您必须首先列出IP范围的模式
case "$arg" in
IP-range) ... ;;
single-IP) ... ;;
esac
然后它首先测试IP范围情况,并且只有当它与单个IP模式的测试不匹配时才会进行测试。
有关简化测试,请参阅
case "$1" in
*.*.*.*-*.*.*.*) echo range ;;
*.*.*.*) echo single ;;
*) echo else ;;
esac
这给出了
$ sh /tmp/a.sh 1.2.3.4
single
$ sh /tmp/a.sh 1.2.3.4-5.6.7.8
range
$ sh /tmp/a.sh 1.2.3
else
答案 1 :(得分:1)
也许这个小循环可以帮助你:
#!/bin/bash
shopt -s extglob
is_a_byte() {
local i
for i do
[[ "$i" = +([[:digit:]]) ]] && ((10#$i<=255)) || return 1
done
}
is_ip() {
local ipn
read -a ipn <<< "${1//./ }"
if [[ "${#ipn[@]}" = 4 ]] && is_a_byte "${ipn[@]}"; then
[[ "$2" ]] && printf -v "$2" "%s" $(( ((((((10#${ipn[0]}<<8)|10#${ipn[1]})<<8)|10#${ipn[2]})<<8)|10#${ipn[3]}) ))
return 0
else
return 1
fi
}
while IFS=- read -e -r -p "Enter an IP or an IP range: " -a ip; do
if [[ -z ${ip[1]} ]]; then
if is_ip "${ip[0]}" N; then
echo "Valid IP ---> $N"
else
echo "${ip[0]} is not a valid IP"
fi
else
if is_ip "${ip[0]}" N[0] && is_ip "${ip[1]}" N[1]; then
((N[0]>N[1])) && N=( "${N[1]}" "${N[0]}" )
echo "Valid IP range ---> ${N[0]}-${N[1]}"
else
echo "${ip[0]}-${ip[1]} is not a valid IP range"
fi
fi
done
没有grep,没有子shell,只有纯粹的bash,它比笨拙的glob / regex更强大,我会说它相当优雅;-)
。