0
172.68.10.245 - - [16/Dec/2020:06:38:03 +0000] "GET /basket/add/36994 HTTP/1.1" 404 314 "http://site.ru/basket/add/36994" "Mozilla/5.0 (X11; OpenBSD i386) AppleWebKit/537.36 (KHTML, like G$
172.68.10.221 - - [16/Dec/2020:06:38:04 +0000] "GET /media/chain/rostelekom.png HTTP/1.1" 304 182 "https://firstmagazin.ru/moskva/tele2" "Mozilla/5.0 (Linux; Android 9; MI 6) AppleWebKit/537.36
172.68.11.72 - - [16/Dec/2020:06:38:08 +0000] "GET /chita/letual/103051 HTTP/1.1" 200 7852 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)"
172.68.11.60 - - [16/Dec/2020:06:38:09 +0000] "GET /kola/pikpoint/110562 HTTP/1.1" 200 6730 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)"


grep "(?:(?!.*?bots.*)172\.68.*|abab)" access_f.log

I'm trying to filter logs file that have an ip mask "172.168." but no substring "bots".

grep error:

-bash: !.bots.: event not found

How best to solve this problem?

CinCout
  • 9,486
  • 12
  • 49
  • 67

2 Answers2

1

Bash by default interprets ! to be a history lookup. You can avoid this by using single quotes around your regex; this is generally a good idea anyway (double quotes are weaker, and will not protect backslashes, dollar signs, or backticks from being interpreted by the shell).

You can and probably should turn off the Csh-style history expansion entirely anyway; see echo "#!" fails -- "event not found"

Standard grep does not support the Perl regex constructs you are trying to use. Some platforms offer grep -P which does have this support, but it is not portable.

A simple, straightforward, portable solution is to use Awk instead.

awk '!/bots/ && /^172\.68\.|abab/' access_f.log

(or \.168\. if that's what you meant).

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Perhaps see also https://stackoverflow.com/questions/18514135/bash-regular-expression-cant-seem-to-match-any-of-s-s-d-d-w-w-etc which has a discussion of how to work around the lack of (some) PCRE features in Bash (but also more broadly any POSIX-style regex tool). – tripleee Jan 20 '22 at 06:24
0

The regular expression given by @CinCout has no errors, but to use PCRE regular expressions in GNU grep, you need to escape and specify options. Try:

grep -Po "172.68(?\!.*bots).*"

enter image description here

Vincent Sit
  • 2,214
  • 1
  • 24
  • 27