在我的 bash 脚本的标题中,我必须询问用户名和他的 IP 地址。
我需要以这种方式验证条目:
- 用户名必须存储在一个
name
变量中,他的空格用下划线代替。对于用户点击的示例"Albert Smith"
,我必须存储"Albert_Smith"
到我的变量name
中。 - 对于ip地址,我需要知道ip地址是否与格式一致。如果格式不好,我必须报错并提示用户输入好的ip地址才能继续操作。
我知道我需要使用“阅读”,但我不知道如何实现我的短脚本(替换和验证)。预先感谢 :)
在我的 bash 脚本的标题中,我必须询问用户名和他的 IP 地址。
我需要以这种方式验证条目:
name
变量中,他的空格用下划线代替。对于用户点击的示例"Albert Smith"
,我必须存储"Albert_Smith"
到我的变量name
中。我知道我需要使用“阅读”,但我不知道如何实现我的短脚本(替换和验证)。预先感谢 :)
还有一种方式。仅重击:
#!/bin/bash
read name
name=${name// /_}
read ip
if [[ "$ip" =~ ^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$ ]]
then
for (( i=1; i<${#BASH_REMATCH[@]}; ++i ))
do
(( ${BASH_REMATCH[$i]} <= 255 )) || { echo "bad ip" >&2; exit 1; }
done
else
echo "bad ip" >&2
exit 1;
fi
echo "name:$name"
echo "ip:$ip"
不完全是问题的答案,但对于那些喜欢“单线”的人来说,IP 验证正则表达式:
[[ "$IP" =~ ^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]] && echo "valid" || echo "invalid"
您可以使用 进行第一部分,使用andtr
进行第二部分:grep
awk
#!/bin/sh
echo "Enter a name:"
read FULL_NAME
FULL_NAME_REPLACED="$(echo $FULL_NAME | tr ' ' _)"
echo $FULL_NAME_REPLACED
echo "Enter an IP address:"
read IP_ADDRESS
if echo "$IP_ADDRESS" | egrep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
then
# Then the format looks right - check that each octect is less
# than or equal to 255:
VALID_IP_ADDRESS="$(echo $IP_ADDRESS | awk -F'.' '$1 <=255 && $2 <= 255 && $3 <= 255 && $4 <= 255')"
if [ -z "$VALID_IP_ADDRESS" ]
then
echo "The IP address wasn't valid; octets must be less than 256"
else
echo "The IP address was valid"
fi
else
echo "The IP address was malformed"
fi
如果找到该线程awk
中使用的表达式。这是对单独使用或单独使用的改进,因为它还将拒绝大于 255 的八位字节,例如.grep
sed
400.400.400.400
我想您的条目将基于行(即名称将是第一行,IP 将是第二行)。你可以这样做:
#!/bin/bash
read name
while [[ ! "$name" =~ '[A-Za-z ]' ]]; do
read -p "Wrong name format. Re-enter: " name
done
name="${name// /_}"
read ip
while [[ ! "$ip" =~ '^((25[0-5]|2[0-4][0-9]|[01][0-9][0-9]|[0-9]{1,2})[.]){3}(25[0-5]|2[0-4][0-9]|[01][0-9][0-9]|[0-9]{1,2})$' ]]; do
read -p "Not an IP. Re-enter: " ip
done
IP 正则表达式相当复杂,但可以分解为:
循环形式将否定!
的结果,因此在命令失败grep
时它将继续循环。grep
我们使用printf
为了将变量传递到grep
. 第二-E
个标志grep
允许使用扩展的正则表达式,包括|
OR 运算符、()
分组和{}
重复。
希望这会有所帮助=)
作为一个函数:
ask4nameIp() {
unset ip name
local var v1 v2 v3 v4
while ! [ "$name" ] || ! [ "$ip" ]; do
printf "Name: %s\r" $name
read -p Name:\ var
[ "$var" ] && name=${var// /_}
printf "IP: %s\r" $ip
IFS=. read -p IP:\ v{1..5}
((${#v1}*${#v2}*${#v3}*${#v4})) &&
[ -z "${v1//[0-9]}${v2//[0-9]}${v3//[0-9]}${v4//[0-9]}$v5" ] &&
((0<=v1&&v1<=255&&0<=v2&&v2<=255&&0<=v3&&v3<=255&&0<=v4&&v4<=255)) &&
ip=$v1.$v2.$v3.$v4
[ "$name" ] && [ "$ip" ] ||
echo something wrong: ${name:-name missing} ${ip:-ip missing}...;
done;
printf "Name: '%s'\nIP: '%s'\n" $name $ip
}
变量$name
和$ip
可以在函数之外使用:
$ ask4nameIp ; declare -p name ip
Name: foo bar 23
IP: 10.123.45.67
Name: 'foo_bar_23'
IP: '10.123.45.67'
declare -- name="foo_bar_23"
declare -- ip="10.123.45.67"
像这样:(完整的 bash!没有管道,没有外部 tr,awk,sed,...)可以在 bash 控制台上使用 cut'n 过去进行测试,无需将其写入脚本文件。
unset name ip; \
while ! [ "$name" ] || ! [ "$ip" ];do
printf "Name: %s\r" $name;
read -p Name:\ var;
[ "$var" ] && name=${var// /_};
printf "IP: %s\r" $ip;
read -p IP:\ var;
iparray=($( IFS=".";echo $var;));
[ ${#iparray[@]} -eq 4 ] && \
[ $iparray -ge 0 ] && [ $iparray -le 255 ] && \
[ ${iparray[1]} -ge 0 ] && [ ${iparray[1]} -le 255 ] && \
[ ${iparray[2]} -ge 0 ] && [ ${iparray[2]} -le 255 ] && \
[ ${iparray[3]} -ge 0 ] && [ ${iparray[3]} -le 255 ] && \
ip=$var;
[ "$name" ] && [ "$ip" ] || echo something wrong...;
done; \
printf "Name: '%s'\nIP: '%s'\n" $name $ip
这看起来比使用 bash 的正则表达式更强大,但在使用中,这要轻得多。
在使用中,这将提示所有已定义变量的请求作为默认值并循环直到定义所有变量:
unset
所有需要的变量print
请求和已经定义的变量(默认\r
)并通过使用而不是保持在同一行\n
read
回答(该请求被重写为上一行提示的请求,在同一个地方)。name
是否有东西name
对变量重复操作: print
request + 已经定义,而不是提示请求和read
anser。iparray
来分割 IP 的整数IP
。echo
除非定义了所有变量,否则会出现错误消息。read name
name=`echo $name|tr ' ' _`
read ip
stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi