¿Cómo verificar si alguna dirección IP está presente en un archivo usando scripting de shell?


13

Tengo un script que genera algunos resultados. Quiero verificar esa salida para cualquier dirección IP como

159.143.23.12
134.12.178.131
124.143.12.132

if (IPs are found in <file>)
then // bunch of actions //
else // bunch of actions //

Es fgrepuna buena idea?

Tengo bash disponible.


use grep, egrep, awk o sed, lo que quiera
Ijaz Ahmad Khan

¿Podría ayudarme con la sintaxis por favor? Quiero decir, ¿cómo busca una IP aleatoria? ¿Cómo describir el patrón? Buscaría cualquier dirección IP, no una dirección particular.
Koshur

55
¿Es eso solo direcciones IPv4 en notación decimal decimal? ¿Podrían ser escritos como 0010.0000.0000.0001? ¿Puede el archivo contener cosas que parecen direcciones IP como números de versión ( soft-1.2.1100.1.tar.gz, especificaciones de red (10.0.0.0/24), 1.2.3.4.5)? ¿Aceptaría una solución que sea positiva en 333.444.555.666? ¿O 0377.0377.0377.0377(una dirección IP quad-octal válida)?
Stéphane Chazelas

Si bashestá disponible, awkgeneralmente también lo está, por lo que esto podría funcionar para usted: awk '/([0-9]{2,3}\.){3}/ {print $5 "\t" $1}'(Esta línea traduce la salida de la lista XFR del host al /etc/hostsformato).
Mark Hudson,

Respuestas:


25

Sí, tiene muchas opciones / herramientas para usar. Acabo de probar esto, funciona:

ifconfig | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"

para que pueda usar grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"grep las direcciones IP de su salida.


Gracias. Esto funciona. ¿Puedes explicar un poco? ¿Es esta una expresión regular?
Koshur

Sí, esta es una expresión regular utilizada en bash con grep, solo está buscando un patrón de tres dígitos separados por puntos. puedes jugar cambiando los números en {1,2} por 2 dígitos consecutivos y así sucesivamente
Ijaz Ahmad Khan

También se puede usar "\b([0-9]{1,3}\.){3}[0-9]{1,3}\/[0-9][0-9]?"para buscar CIDR (suponiendo que sean válidos)
vikas027

2

comenzando mi respuesta basada en esta respuesta:

Sí, tiene muchas opciones / herramientas para usar. Acabo de probar esto, funciona:

ifconfig | grep -oE "\ b ([0-9] {1,3}.) {3} [0-9] {1,3} \ b" a para que pueda usar grep -oE "\ b ([0- 9] {1,3}.) {3} [0-9] {1,3} \ b "para grep las direcciones IP de su salida.

y convertir la respuesta a IPv6 de longitud completa, etc.

fgrep -oE "\b([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}\b" -- file

si quieres mantener el / nnn si está ahí:

fgrep -oE "\b([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}(/[0-9]{1,3}){0,1}\b" -- file

y también está la versión abreviada de IPv6 que incluye '::'.

Para obtener más respuestas de IPv6, puede consultar aquí: /programming/53497/regular-expression-that-matches-valid-ipv6-addresses


fgrepes el nombre antiguo de una variante grepque ignora la coincidencia de patrones. Me gustaría recomendar que utilice grep(o incluso egrep) en lugar, especialmente en lo que está claramente querer coincidencia de patrones.
roaima

2

Si su archivo se llama, por ejemplo ips, puede escribir algo como:

while read -r ip
    do
        if [[ $ip == "$1" ]]; then
            shift
            printf '%s\n' 'action to take if match found'
        else
            printf '%s\n' 'action to take if match not found'
        fi
    done < ips

Luego puede pasar los parámetros como sigue el script

./myscript 159.143.23.12 134.12.178.131 124.143.12.132 124.143.12.132

0

Si tiene la lista de IP en un archivo, una por línea, grepya tiene la -fopción conveniente :

$ man fgrep | grep file= -A1
       -f FILE, --file=FILE
              Obtain patterns from FILE, one per line.  The empty file contains zero patterns, and therefore matches nothing.  (-f is specified by POSIX.)

Esto puede causar algunos falsos positivos debido a cadenas opcionalmente seguidas de otro número para que sea una IP diferente. Muchas cosas que puede hacer al respecto, dependiendo de su caso, puede decidir o no preocuparse.


0

Probado en SmartOS (una variante de Solaris), con suerte debería funcionar en otros entornos * nix:

egrep '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])'

Ejemplo:

$ cat >file.txt
IP1: 192.168.1.1
IP2: 261.480.201.311
IP3: 1012.680.921.3411

$ egrep '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])' file.txt
IP1: 192.168.1.1

Este patrón solo coincide con IPv4 válido , es decir, x.x.x.xdonde el xrango va de 0 a 255. Si necesita extraer solo la IP coincidente, agregue una -oopción al comando anterior. Podría incrustar este comando en un script bash y presumiblemente también en otros scripts de shell. Y, si egrepfalla,try grep -E ...

Utilizándolo en un script de shell (bash):

ip=$(egrep -o '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])' file.txt) echo $ip


0

Creo que mi respuesta a otra publicación es más adecuada aquí. Gracias a esta publicación y a otras similares, se me ocurrió esto, que busca el formato IP correcto y luego elimina todas las líneas que contienen 256 o más. Reemplace la IP con algo que no sea válido para no ver ninguna salida en su lugar:

echo '255.154.12.231' | grep -E '(([0-9]{1,3})\.){3}([0-9]{1,3}){1}' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]'

El primer grep probablemente se encontró en esta publicación y verifica los números del 0-999 en el formato XXXX

El segundo grep elimina líneas con números 256-999, dejando solo direcciones IP de formato válidas, así que pensé

PERO ... Como señaló G-Man, estaba en un error al suponer que la IP estaría en su propia línea. Sin embargo, la mayoría de las veces habrá un espacio u otro divisor para buscar a ambos lados de la IP. Los espacios / divisores se pueden eliminar con sed u otros medios después de encontrar la IP. También agregué -o al primer grep:

echo ' 1234.5.5.4321 ' | grep -Eo ' (([0-9]{1,3})\.){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'

echo ' 234.5.5.432 ' | grep -Eo ' (([0-9]{1,3})\.){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'
echo ' 234.5.5.100 ' | grep -Eo ' (([0-9]{1,3})\.){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'

El primero y el segundo no darán salida, mientras que el tercero sí y los espacios se eliminarán.


Supongamos que tengo 500 direcciones, que van desde 10.0.0.1 a 10.0.1.244. Su segundo greptiraría esa línea debido a los "500". (La pregunta nunca dijo que las direcciones IP en el archivo, si las hubiera, estarían en una línea por sí mismas). Por otro lado, aceptará 1234.1.1.1 y 1.1.1.1234. Pero aparte de eso, no está mal.
G-Man dice 'reinstalar a Mónica' el

-1

Redirigir esa salida a algunos outputFile

Simplemente grepcon patrón como,

grep -sE "159.143.23.12|134.12.178.131|124.143.12.132" <outputFile>

44
Tenga en cuenta que .es un operador de expresión regular y necesita escapar para que sea tratado literalmente
Stéphane Chazelas

1
Esos no son patrones, esos son literales. No es una respuesta útil ya que el OP especificó "cualquier IP".
Mark Hudson el

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.