这是根据需要纯粹使用 Bash 处理它的一种方法。没有 awks、sed 和其他东西。
#!/bin/bash
shopt -s extglob
IFS=,
while read -r LINE; do
OUTPUT=()
while [[ -n $LINE ]]; do
case "$LINE" in
+([[:digit:]]).+([[:digit:]]).+([[:digit:]]).+([[:digit:]]))
OUTPUT[${#OUTPUT[@]}]=$LINE
break
;;
+([[:digit:]]).+([[:digit:]]).+([[:digit:]]).+([[:digit:]]),*)
OUTPUT[${#OUTPUT[@]}]=${LINE%%,*}
LINE=${LINE#*,}
;;
+([[:digit:]]).+([[:digit:]]).+([[:digit:]]).\[+([[:digit:],-])\]*)
SET=${LINE%%\]*}
PREFIX=${SET%%\[*}
read -a RANGES <<< "${SET:${#PREFIX} + 1}"
for R in "${RANGES[@]}"; do
case "$R" in
+([[:digit:]]))
OUTPUT[${#OUTPUT[@]}]=${PREFIX}${R}
;;
+([[:digit:]])-+([[:digit:]]))
X=${R%%-*} Y=${R##*-}
if [[ X -le Y ]]; then
for (( I = X; I <= Y; ++I )); do
OUTPUT[${#OUTPUT[@]}]=${PREFIX}${I}
done
else
for (( I = X; I >= Y; --I )); do
OUTPUT[${#OUTPUT[@]}]=${PREFIX}${I}
done
fi
;;
esac
done
LINE=${LINE:${#SET} + 2}
;;
*)
# echo "Invalid token: $LINE" >&2
break
esac
done
echo "${OUTPUT[*]}"
done
对于输入
192.168.38.[217,222],192.168.40.215,192.168.41.[219-222]
运行 bash temp.sh < temp.txt 产生
192.168.38.217,192.168.38.222,192.168.40.215,192.168.41.219,192.168.41.220,192.168.41.221,192.168.41.222
它也与范围一致。如果 X 晚于 Y,例如 200-100,那么它将生成 IPS,其子集为 200 到 100。该脚本还可以处理多行输入。
它还应该适用于 [100,200-250] 等混合范围。