请建议如何从 file.txt 中仅匹配有效 IP(255.255.255.255)并将有效 IP 插入到 VALID_IP.txt 文件中
- (例如,参见 VALID_IP.txt)
解决方案应该在我的 ksh 脚本中实现(因此 perl 或 sed 或 awk 也可以)
更多文件.txt
e32)5.500.5.5*kjcdr
##@$1.1.1.1+++jmjh
1.1.1.1333
33331.1.1.1
@5.5.5.??????
~3de.ede5.5.5.5
1.1.1.13444r54
192.9.30.174
&&^#%5.5.5.5
:5.5.5.5@%%^^&*
:5.5.5.5:
**22.22.22.22
172.78.0.1()*5.4.3.277
VALID_IP.txt 文件示例
1.1.1.1
192.9.30.174
5.5.5.5
5.5.5.5
5.5.5.5
22.22.22.22
172.78.0.1
答案1
以下是合适的正则表达式,为了我自己的理智起见,将其分成 4 行。
(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.
(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.
(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.
(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])
输出:
egrep -o `cat regex` infile #all regex lines above joined, no spaces
1.1.1.1
1.1.1.133
31.1.1.1
5.5.5.5
1.1.1.134
192.9.30.174
5.5.5.5
5.5.5.5
5.5.5.5
22.22.22.22
172.78.0.1
5.4.3.27
显然这与您的示例不符。为什么?因为我们无法分辨 3 不属于 1。如您所见,垃圾数字无法被干净地猜出。
答案2
使用 perl 会更简洁一些
#!/usr/bin/perl
use Regexp::Common qw/net/;
while (<>) {
print $1, "\n" if /($RE{net}{IPv4})/;
}
但仍然会出现误报
1.1.1.1
1.1.1.133
31.1.1.1
5.5.5.5
1.1.1.134
192.9.30.174
5.5.5.5
5.5.5.5
5.5.5.5
22.22.22.22
172.78.0.1
Perl 一行程序
perl -e 'use Regexp::Common qw/net/;while (<>) {print $1, "\n" if /($RE{net}{IPv4})/;}' infile
答案3
我建议使用范围检查而不是复杂的正则表达式。您可以在 ksh 中执行此操作,而无需使用外部实用程序或其他语言。虽然 Iain 的解决方案很好,但它不是核心模块。
这是纯 ksh。无需将其变成一行代码,只需使用函数即可。这样的代码更容易理解、更容易检查正确性并且更容易维护。
#!/usr/bin/ksh
validate_ip () {
typeset ip=$@
typeset IFS=. valid=1
typeset octets=($ip) octet
typeset digits='^[[:digit:]]+$'
if (( ${#octets[@]} == 4 ))
then
for ((octet = 0; octet <= 3; octet++))
do
value=${octets[octet]}
if [[ ! "$value" =~ $digits ]] || ((value < 0 || value > 255))
then
valid=0
fi
done
else
valid=0
fi
if ((valid))
then
printf '%s\n' "$ip"
fi
return $valid
}
while read -r line
do
validate_ip "$line"
done #< file.txt > VALID_IP.txt
这是 ksh 93,我还没有在 ksh 88 中测试过它。它也可以在 Bash 3.2 或更高版本中不加更改地运行。