пожалуйста, посоветуйте, как сопоставить только действующие IP-адреса (255.255.255.255) из файла file.txt и вставить только действительный IP в файл VALID_IP.txt
решение должно быть реализовано в моем скрипте ksh (так что perl, sed или awk тоже подойдут)
больше file.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
Следующее - подходящее регулярное выражение, разделенное на 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
Очевидно, это не соответствует вашему примеру. Зачем? Потому что мы не можем сказать, что тройка не принадлежит единице. Как видите, невозможно точно угадать количество мусора.
Это немного чище с 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
Я рекомендую использовать проверку диапазона вместо волосатых регулярных выражений. Вы можете сделать это в 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 или выше.