写一个脚本统计文件nowcoder.txt中的每一行是否是正确的IP地址。
如果是正确的IP地址输出:yes
如果是错误的IP地址,且是四段号码的话输出:no,否则的话输出:error
假设nowcoder.txt内容如下:
192.168.1.1
192.168.1.0
300.0.0.0
123
你的脚本应该输出:
yesyesnoerror
192.168.1.1
192.168.1.0
300.0.0.0
123
yesyesnoerror
192.168.1.1 192.168.1.0 300.0.0.0 123
yes yes no error
while read line
do
arr=(${line//./ })
if [ ${#arr[*]} -ne 4 ];then
printf "error\n"
else
for ((i=0; i<${#arr[*]}; i++))
do
[ ${arr[${i}]} -gt 255 ] && printf "no\n" && break
done
[ $i == 4 ] && printf "yes\n"
fi
done 纯awk awk -F "." '{
if (NF == 4) {
for (i=1; i<5; i++) {
if ($i > 255 || $i < 0) {
print("no");break
}
}
if (i==5){print("yes")}
} else {
print("error")
}
}' 纯awk 正则匹配版本awk -F "." '{
if (NF == 4) {
if ($0 ~ /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[09][0-9]|[1-9][0-9]|[0-9])$/) {
print("yes")
} else {
print("no")
}
} else {
print("error")
}
}'
awk -F'.' '{if(NF!=4){print "error";next}else{for(i=1;i<=4;i++){if(i==4){print "yes";next}else{if($i<0||$i>255){print "no";next}}}}}' nowcoder.txt 完全依靠awk的next功能实现,如果中途有一个字段不符合要求,都输出no,并且处理下一行;如果进入到最后一个字段,依然没有退出,只能说明,当前行的所有字段都是符合要求的,但是又不能在for中打印,不然会重复打印yes,于是在此前加上一个if识别四个字段都合法的情况
此题关键在于正则匹配
0-255数字匹配
- 0-99匹配表达式:[1-9]?[0-9]
- 100-199匹配表达式:1[0-9]{2}
- 200-249匹配表达式:2[0-4][0-9]
- 250-255匹配表达式:25[0-4]
- 0-255 匹配表达式:[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4]
正确ip的匹配表达式:^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])$河边小石子题解如下:
#!/bin/bash
ip_yes='^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])$'
ip_no='^([0-9]+\.){3}([0-9]+)$'
while read line;
do
if [[ $line =~ $ip_no ]];then #注意=~
if [[ $line =~ $ip_yes ]];then
echo "yes"
else
echo "no"
fi
else
echo "error"
fi
done<./nowcoder.txt
#!/bin/bash
while IFS= read -r line || [ -n "$line" ]; do
# 检查是否为空行
if [ -z "$line" ]; then
echo "error"
continue
fi
# 初步检查格式:必须是 X.X.X.X 形式,且只含数字和点
case "$line" in
*[!0-9.]* | .* | *. | *..* | "")
echo "error"
continue
;;
esac
# 按 . 分割,存入数组(不使用 here-string)
OIFS=$IFS
IFS='.'
set -- $line # 使用 set -- 避免 here-string
IFS=$OIFS
# 必须恰好 4 段
if [ $# -ne 4 ]; then
echo "error"
continue
fi
a=$1; b=$2; c=$3; d=$4
# 检查每一段
for octet in "$a" "$b" "$c" "$d"; do
# 空段(如 192..1.1)已在前面过滤,这里再保险
if [ -z "$octet" ]; then
echo "no"
continue 2
fi
# 检查前导零:长度>1 且首字符为0 → 非法
if [ ${#octet} -gt 1 ] && [ "${octet:0:1}" = "0" ]; then
echo "no"
continue 2
fi
# 检查是否为数字(防止非数字,虽然前面已过滤)
case "$octet" in
*[!0-9]*)
echo "no"
continue 2
;;
esac
# 检查范围 0~255
if [ "$octet" -lt 0 ] || [ "$octet" -gt 255 ]; then
echo "no"
continue 2
fi
done
echo "yes"
done < nowcoder.txt cat ip.txt | while read line;do echo $line | awk -F. '{if(NF==4 && $1<=255 ){print "yes"} else if(NF==4 && $1>255){print "no"} else{print "error"} }';done