Come verificare se un indirizzo IP è presente in un file usando lo script della shell?


13

Ho uno script che genera un output. Voglio controllare quell'output per qualsiasi indirizzo IP simile

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 //

È fgrepuna buona idea?

Ho bash disponibile.


usa grep, egrep, awk o sed, come preferisci
Ijaz Ahmad Khan,

Potresti aiutare con la sintassi per favore? Voglio dire come cerca un IP casuale. Come descrivere il modello? Vorrei cercare qualsiasi indirizzo IP, non un indirizzo particolare.
Koshur,

5
Sono solo indirizzi IPv4 in notazione quad-decimale? Potrebbero essere scritti come 0010.0000.0000.0001? Il file potrebbe altrimenti contenere elementi che sembrano indirizzi IP come numeri di versione ( soft-1.2.1100.1.tar.gz, specifiche di rete (10.0.0.0/24), 1.2.3.4.5)? Accetteresti una soluzione positiva su 333.444.555.666? O 0377.0377.0377.0377(un indirizzo IP quad-ottale valido)?
Stéphane Chazelas,

Se bashè disponibile, allora di awksolito lo è anche, quindi potrebbe funzionare per te: awk '/([0-9]{2,3}\.){3}/ {print $5 "\t" $1}'(Questo one-liner traduce l'output dell'elenco XFR host in /etc/hostsformato.)
Mark Hudson,

Risposte:


25

Sì, hai molte opzioni / strumenti da usare. Ho appena provato questo, funziona:

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

in modo da poter utilizzare grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"per grep gli indirizzi IP dall'output.


Grazie. Questo funziona Puoi spiegarci un po '? È un'espressione regolare?
Koshur,

Sì, questa è un'espressione regolare usata in bash con grep, stai solo cercando un modello a tre cifre separato da punti. puoi giocare cambiando i numeri in {1,2} per 2 cifre consecutive e così via
Ijaz Ahmad Khan,

Si può anche usare "\b([0-9]{1,3}\.){3}[0-9]{1,3}\/[0-9][0-9]?"per trovare CIDR (supponendo che siano validi)
vikas027

2

iniziare la mia risposta in base a questa risposta:

Sì, hai molte opzioni / strumenti da usare. Ho appena provato questo, funziona:

ifconfig | grep -oE "\ b ([0-9] {1,3}.) {3} [0-9] {1,3} \ b" a in modo da poter usare grep -oE "\ b ([0- 9] {1,3}.) {3} [0-9] {1,3} \ b "per visualizzare gli indirizzi IP dall'output.

e convertendo la risposta in IPv6 a lunghezza intera, ecc ...:

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

se vuoi mantenere / nnn se è lì:

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

e c'è anche la versione abbreviata di IPv6 che include '::'.

per ulteriori risposte IPv6 puoi consultare qui: /programming/53497/regular-expression-that-matches-valid-ipv6-addresses


fgrepè il vecchio nome di una variante grepche ignora la corrispondenza dei modelli. Ti consiglierei di usare grep(o anche egrep) invece, specialmente perché stai chiaramente cercando la corrispondenza del modello.
roaima,

2

Se il tuo file si chiama ad es. ipsPuoi scrivere qualcosa del tipo:

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

Quindi è possibile passare i parametri come seguire lo script

./myscript 159.143.23.12 134.12.178.131 124.143.12.132 124.143.12.132

1

Testato su SmartOS (una variante di Solaris), si spera che funzioni in altri ambienti * 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])'

Esempio:

$ 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

Questo modello corrisponde solo valida IPv4, cioè, x.x.x.xin cui xvanno 0-255. Se è necessario estrarre solo l'IP corrispondente, aggiungere -oun'opzione al comando sopra. Potresti incorporare questo comando in uno script bash e presumibilmente anche in altri script shell. E, se egrepfallisce,try grep -E ...

Usandolo in uno script di 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


Funzionava bene su un sistema CentOS 6, grep 2.6.3
David Ramirez

0

Se hai un elenco di IP in un file, uno per riga, hai grepgià l' -fopzione 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.)

Ciò può causare alcuni falsi positivi dovuti alle stringhe opzionalmente seguite da un altro numero per renderlo un IP diverso. Molte cose che puoi fare al riguardo, a seconda del caso, potresti decidere di non preoccuparti.


0

Penso che la mia risposta a un altro post sia più adatta qui. Grazie a questo post e ad altri simili, ho pensato a questo, che cerca il formato IP corretto, quindi elimina tutte le righe che contengono 256 o superiore. Sostituisci l'IP con qualcosa che non è valido per non visualizzare invece output:

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]'

Il primo grep è stato probabilmente trovato in questo post e controlla eventuali numeri da 0 a 1999 nel formato XXXX

Il secondo grep rimuove le righe con i numeri 256-999, lasciando quindi solo IP di formato validi, così ho pensato

MA ... Come sottolineato da G-Man, mi sbagliavo supponendo che l'IP fosse sulla sua stessa linea. Quasi sempre, ci sarà uno spazio o un altro divisore da cercare su entrambi i lati dell'IP. Gli spazi / divisori possono essere rimossi con sed o altri mezzi dopo aver trovato l'IP. Ho anche aggiunto -o al primo 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/ //'

Il primo e il secondo non daranno alcun output, mentre il terzo lo farà e gli spazi verranno eliminati.


Supponiamo che io abbia 500 indirizzi, che vanno da 10.0.0.1 a 10.0.1.244. Il tuo secondo grepeliminerebbe quella linea a causa del "500". (La domanda non ha mai detto che gli indirizzi IP nel file, se presenti, sarebbero su una riga da soli.) D'altra parte, accetterà 1234.1.1.1 e 1.1.1.1234. Ma a parte questo, non male.
G-Man dice "Ripristina Monica" il

-1

Reindirizza l'output su alcuni outputFile

Semplicemente grepcon motivo come,

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

4
Si noti che .è un operatore di espressioni regolari e ha bisogno di scappare per essere trattato alla lettera
Stéphane Chazelas,

1
Quelli non sono schemi, quelli sono letterali. Non è una risposta utile poiché l'OP ha specificato "qualsiasi IP".
Mark Hudson,

-1
ip -4  addr show eth1 |  grep -oP '(?<=inet\s)\d+(\.\d+){3}'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.