Grep IP с точным совпадением и совпадением между случайными строками

#string #bash #grep

#строка #bash #grep

Вопрос:

Я пытаюсь отобразить следующий входной файл, содержащий IP-адрес. Я хочу отобразить точное совпадение между строками, как показано в примере, но, похоже, это не увенчалось успехом. Для демонстрации вот пример данных внутри текстового файла с именем input.txt :

 1. IP [1.1.1.1] 
2. IP [1.1.1.11] 
3. IP [1.1.1.115]
4. IP "1.1.1.1 " 
5. IP "1.1.1.11 "
6. IP "1.1.1.115"
7. IP U*@K1.1.1.1-I(M@ 
8. IP *JJ1.1.1.11()
9. IP *J@K1.1.1.115U*@ 
10. IP U#@I1.1.1.19lds
  

Итак, допустим, я хочу найти этот IP: 1.1.1.1 , я напишу следующий код:

 grep -w '1.1.1.1' input.txt
  

При этом я получил следующий результат:

 1. IP [1.1.1.1]
4. IP "1.1.1.1 "
  

Но ожидаемый результат таков: 7-я строка также должна отображаться, потому что она содержит IP 1.1.1.1 между случайной строкой. Таким образом, ожидаемый результат должен быть таким:

 1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
  

И теперь допустим, я хочу найти эту строку: 1.1.1 :

 grep -w '1.1.1' input.txt
  

и я получил следующий результат:

 1. IP [1.1.1.1]
2. IP [1.1.1.11]
3. IP [1.1.1.115]
4. IP "1.1.1.1 "
5. IP "1.1.1.11 "
6. IP "1.1.1.115"
7. IP U*@K1.1.1.1-I(M@
  

Ожидаемый результат: он не должен ничего возвращать, потому что вся строка 1.1.1 не находится внутри input.txt .

Способен ли grep это сделать?

Комментарии:

1. да, и он просто отображает тот же неожиданный вывод с 1-й строки до 7-й строки. @blurfus

2. grep "<1.1.1>" input.txt также выдает тот же результат с 1-й строки до 7-й строки

3. Меня смущает вопрос. Вы ожидаете, что это IP U*@K1.1.1.1-I(M@ будет совпадать 1.1.1.1 , даже если это не полностью слово (т. Е. K1 ), Но Тогда вы ожидаете, что ничего не будет совпадать 1.1.1 с тем же вводом? — как насчет того же K1 сценария?

4. Если на входе есть это: 1.1.1-2 он должен отображаться, потому что там есть 1.1.1. Но если вывод такой 1.1.1.3 , он не должен отображаться. короче говоря, если после этой строки 1.1.1 появляется точка или число, это недопустимо. Возможно, это то, что он имел в виду.

5. @blurfus IP-адрес должен совпадать между случайными строками. Примером допустимого IP-адреса между случайной строкой является этот UIO@#J1.1.1.1J@ или *JKJHH9.1.3.2{}@PO или xjk29)192.111.22.3p или в реальном файле журнала: http://1.2.3.4/test?ok или http://local/match.php?amp;abc=1.2.2.2amp;a

Ответ №1:

Упрощайте и будьте более понятными.

 $: grep '[^.0-9]1.1.1.1[^.0-9]' txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
  

Однако это все еще ошибочно — добавьте еще одну запись к вашим тестовым данным.

 $: grep '[^.0-9]1.1.1.1[^.0-9]' txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
11. IP [1a1b1c1]
  

Затем попробуйте это:

 $: grep '[^.0-9]1.1.1.1[^.0-9]' txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
  

Это по-прежнему не учитывает возможность IP-адреса в самых концах строки, так что, если это вообще возможно,

 $: grep -E '(^|[^.0-9])1.1.1.1([^.0-9]|$)' txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
12. IP 1.1.1.1
  

Если IP вводится как переменная, вы можете заключить его в кавычки.

 $: ip=1.1.1.1
$: echo "grep -E '(^|[^.0-9])${ip//./\.}([^.0-9]|$)'"
grep -E '(^|[^.0-9])1.1.1.1([^.0-9]|$)'
$: grep -E "(^|[^.0-9])${ip//./\.}([^.0-9]|$)" txt
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@
12. IP 1.1.1.1
  

Это может быть проблематично, если ваши шаблоны становятся сложными, но здесь работает нормально.

Комментарии:

1. Спасибо, я добавлю больше входных данных и протестирую. Поддержал ваш ответ.

2. Мне нравится ответ, но что, если входные данные являются переменными, например ip =»1.2.3.2″, и тогда как мы собираемся изменить эту переменную, чтобы иметь такой escape ?. grep -E '(^|[^.0-9])${ip}([^.0-9]|$)' txt ? Работает ли это с переменной?

Ответ №2:

 $ grep '[^[:digit:].]1.1.1.1[^[:digit:].]' file
1. IP [1.1.1.1]
4. IP "1.1.1.1 "
7. IP U*@K1.1.1.1-I(M@

$ grep '[^[:digit:].]1.1.1[^[:digit:].]' file
$
  

Комментарии:

1. Спасибо, я добавлю больше входных данных и протестирую. Поддержал ваш ответ.

2. Я вернулся к этому решению, и я думаю, что это работает лучше, включая ipv6. Тестирование еще немного.

3. Но это не сработает, если ipv6 заканчивается или начинается с алфавита, такого как 240e:00f7:4f01:000c: 0000:0000:0000:0003:ee