Mario Jost
Mario Jost

Reputation: 284

Regex match only if string is found once on multiple lines

Similar questions have been asked before but i cant find anything that covers my scenario. I need a regex that only matches, if a certain string has been found only once on multiple lines. Given following lines:

  20    7c2f.80e9.0b33    DYNAMIC     Gi1/0/27
  20    7c2f.80ee.c28c    DYNAMIC     Gi1/0/47
  20    7c2f.80ee.c2af    DYNAMIC     Gi1/0/47
  20    7c2f.80ee.c2fb    DYNAMIC     Gi1/0/47
  20    7c2f.80f3.6daa    DYNAMIC     Gi1/0/32
  20    7c2f.80f3.6df9    DYNAMIC     Gi1/0/47
  20    7c2f.80f6.f3c8    DYNAMIC     Gi1/0/30
  20    7c2f.80f6.f3fd    DYNAMIC     Gi1/0/29

I need a regex that matches only if the interface has been found once in the string. What i have so far, but it does not work:

(Gi1\/0\/47)[\S\s]*(?!Gi1\/0\/47)

Test it out here: https://regex101.com/r/39yJWm/1

So for example, if I check with Gi1/0/27 it should get a match because it occurs only once. If I check with Gi1/0/47 it shouldn't give a match, cause it occurs 4 times. You only need to consider one interface checking in the regex, as i will loop thru the results with a different interface each time.

Upvotes: 1

Views: 290

Answers (2)

user557597
user557597

Reputation:

Not twice in the string: (?s)^(?!.*Gi1/0/27.*Gi1/0/27).*Gi1/0/27

 (?s)                              # Dot-all modifier
 ^                                 # BOS
 (?! .* Gi1/0/27 .* Gi1/0/27 )     # Not twice in string
 .* 
 Gi1/0/27                          # Must exist

Upvotes: 2

thb
thb

Reputation: 14434

That was tricky. Assuming that the data are in a file named data and you have GNU Sed, here you go:

PAT='Gi1/0/27' && sed -rne '\%'"${PAT}"'$%!d;${p;q0};h;:a;n;\%'"${PAT}"'$%q0;${g;p;q0};ba' data

(If using a tool like Sed is not an option, then, well, I think that you will probably want some kind of tool. This one is hard to do with a regex alone.)

Upvotes: 0

Related Questions