Як перевірити наявність будь-якої IP-адреси у файлі за допомогою сценарію оболонки?


14

У мене є сценарій, який генерує деякий вихід. Я хочу перевірити цей вихід на наявність будь-якої IP-адреси

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

Це fgrepгарна ідея?

У мене є доступний баш.


використовувати grep, egrep, awk або sed, що завгодно
Ijaz Ahmad Khan

Чи можете ви допомогти з синтаксисом, будь ласка? Я маю на увазі, як він шукає випадковий IP. Як описати візерунок? Я б шукав будь-яку IP-адресу, а не конкретну адресу.
Кошур

5
Це лише IPv4 адреси в чотирьохдесяткових позначеннях? Чи могли вони бути написані так 0010.0000.0000.0001? Чи може файл у іншому випадку містити речі, схожі на IP-адреси, наприклад номери версій ( soft-1.2.1100.1.tar.gz, специфікації мережі (10.0.0.0/24), 1.2.3.4.5)? Чи прийняли б ви рішення, яке є позитивним щодо 333.444.555.666? Або 0377.0377.0377.0377(дійсна чотирикутна IP-адреса)?
Стефан Шазелас

Якщо bashце доступно, awkзазвичай це також є, тому це може працювати для вас: awk '/([0-9]{2,3}\.){3}/ {print $5 "\t" $1}'(Цей однолінійний переклад виводить список хостів XFR у /etc/hostsформат.)
Марк Хадсон

Відповіді:


27

Так, у вас є багато варіантів / інструментів для використання. Я просто спробував це, це працює:

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

тож ви можете grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"скопіювати IP-адреси зі свого результату.


Спасибі. Це працює. Ви можете трохи пояснити? Це регулярний вираз?
Кошур

Так, це регулярний вираз, що використовується в bash з grep, ви просто шукаєте трицифровий візерунок, розділений крапками. Ви можете грати, змінюючи числа в {1,2} протягом двох цифр поспіль тощо
Ijaz Ahmad Khan

Можна також "\b([0-9]{1,3}\.){3}[0-9]{1,3}\/[0-9][0-9]?"знайти CIDR (якщо припустити, що вони дійсні)
vikas027

2

починаючи свою відповідь на основі цієї відповіді:

Так, у вас є багато варіантів / інструментів для використання. Я просто спробував це, це працює:

ifconfig | grep -oE "\ b ([0-9] {1,3}.) {3} [0-9] {1,3} \ b" a, щоб ви могли використовувати grep -oE "\ b ([0- 9] {1,3}.) {3} [0-9] {1,3} \ b ", щоб зібрати IP-адреси з вашого виводу.

і перетворення відповіді на повну довжину IPv6 тощо ...:

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

якщо ви хочете зберегти / nnn, якщо він є:

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

а також є скорочена версія IPv6, яка включає "::".

більше відповідей на IPv6 ви можете подивитися тут: /programming/53497/regular-expression-that-matches-valid-ipv6-adadresses


fgrep- це стара назва для варіанта, grepякий ігнорує відповідність шаблону. Я б рекомендував використовувати натомість grep(або навіть egrep), тим більше що ви чітко бажаєте відповідності шаблону.
roaima

2

Якщо ваш файл викликається, наприклад, ipsви можете написати щось таке:

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

Потім ви можете передати параметри, як слідувати сценарію

./myscript 159.143.23.12 134.12.178.131 124.143.12.132 124.143.12.132

1

Протестований у SmartOS (варіант Solaris), сподіваємось, він повинен працювати в інших * 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])'

Приклад:

$ 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

Цей зразок відповідає лише дійсному IPv4, тобто x.x.x.xтам , де xдіапазон від 0-255. Якщо вам потрібно витягнути лише відповідний IP, додайте -oпараметр до вищевказаної команди. Ви можете вбудувати цю команду в bash-скрипт, і, мабуть, і в інші сценарії оболонки. І якщо egrepне вдасться,try grep -E ...

Використовуючи його в сценарії оболонки (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


Це добре працювало в системі CentOS 6, grep 2.6.3
Девід Рамірес

0

Якщо у вас є список IP-адрес у файлі, по одному на рядок, grepвже є зручна -fопція:

$ 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.)

Це може призвести до декількох помилкових позитивних результатів через рядки, необов'язково наступні за іншим номером, щоб зробити його іншим IP. Безліч речей, які ви можете зробити з цим, залежно від вашого випадку, ви можете, а може і не вирішите хвилюватися.


0

Я думаю, що моя відповідь на інший пост тут краще підходить. Завдяки цій публікації та іншим, як вона, я придумав це, що шукає правильний формат IP, а потім позбавляється від усіх рядків, що містять 256 або вище. Замініть IP на щось, що недійсне, щоб замість нього не було результатів:

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

Перший греп, мабуть, був знайдений у цій публікації, і він перевіряє наявність чисел від 0-999 у форматі XXXX

Другий греп прибирає рядки з цифрами 256-999, таким чином залишаючи лише дійсні IP-файли формату, тому я подумав

АЛЕ ... Як вказував G-Man, я помилявся, вважаючи, що IP-адреса буде власною. Однак, як правило, завжди є пробіл або інший роздільник, який потрібно шукати з обох сторін IP-адреси. Пробіли / роздільники можна видалити за допомогою sed або іншими засобами після знаходження IP-адреси. Я також додав -o до першого 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/ //'

Перший і другий не дають результатів, а треті - і пробіли позбавлені.


Припустимо, у мене є 500 адрес, починаючи від 10.0.0.1 до 10.0.1.244. Ваш другий grepвикине цю лінію через "500". (У запитанні ніколи не було сказано, що IP-адреси у файлі, якщо такі є, будуть самі по собі рядки.) З іншого боку, він приймає 1234.1.1.1 та 1.1.1.1234. Але окрім цього, непогано.
G-Man каже: "Відновіть Моніку"

-1

Перенаправити цей вихід на деякі outputFile

Просто grepце з малюнком як,

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

4
Зауважте, що .це оператор регулярних виразів і йому потрібно врятуватися, щоб це було досліджено буквально
Stéphane Chazelas

1
Це не зразки, це буквальні. Не корисна відповідь, оскільки в ОП вказано "будь-який IP".
Марк Хадсон

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.