0

I need to match a line ONLY if it starts with the @ symbol and also contains a single 'A' character, not in a string with other characters. Just the @ and the A need, not SOA for example. Trying to this with grep -P method.

Zone file fragment:

@            IN     SOA     some.bogus.com hostmaster.bogus.com. (
@            IN     A       12.34.56.789
             IN     A       012.345.678.9
@     1800   IN     AAAA    789237:mou68:028n:0000:8afn:
@            IN     NS      ns500.mydummy.server.
@            IN     TXT     "v=spf1 mx ~all"

Using grep -P "(^|\s)\K@(?=\s|$)" myzonefile.com get the lines with @ symbol just fine, but how do I modify it to get the lines with the @ symbol AND with a single 'A' character?

This grep -P '(?=.*@)(?=.*A)' myzonefile.com gets the second line, which is correct, but also gets the SOA line, which I do not want.

This grep -E '\b[A]\s' myzonefile.com gets all lines with single 'A' character only but I have been unable to include an AND operation to also match the @ sign too without piping to another grep. SO not an option.

Should I use sed or awk for this, better suited?

  • 1
    A line begins with `'@'` and contains exactly one `'A'` if it is matched by the regular expression `^@[^A\r\n]*A[^A\r\n]*$` with flags m ("multiline": '^' and '$' are beginning of-line and end-of-line anchors, respectively) and g ("global": do not return after first match) set. [Demo](https://regex101.com/r/4lzrlV/1). The expression reads, "Match '@' at the beginning of the string followed by zero or more characters other than 'A' and line terminators, followed by 'A', followed by zero or more characters other than 'A' and line terminators at the end of the string". – Cary Swoveland Aug 07 '23 at 18:08
  • @CarySwoveland How can I go about accounting for something like the 3rd line? Such as, nothing but whitespace before the first field, or characters are encountered, and then the A after that? The reason for this would be to remove any line that starts with '@' and has an exact 'A', or any line that starts with whitespace and has an exact 'A'. Something like `awk '$1 !~ /^\s*I/ || $2!="A"' myzonefile.com , but with grep -P. – humbleStrength Aug 07 '23 at 20:19
  • I revised my post. I need to not have a match unless the A and @ are isolated characters, not mixed into a string. – humbleStrength Aug 07 '23 at 20:48
  • Your first sentence is clear, that you wish to match lines that begin with `'@'` and contain exactly one `'A'` that is preceded and followed by a whitespace. (I assume `'A'` cannot be at the end of the line.) According to that only the second line in your example is to be matched. Do you also wish to match the third line in your example? If so you need to edit the question to clarify the requirement and also indicate which line(s) in your example are to be matched, and why. – Cary Swoveland Aug 08 '23 at 03:36

4 Answers4

1

With grep and word boundaries (\b):

grep '^@.*\bA\b' myzonefile.com

or

sed -n '/^@.*\bA\b/p' myzonefile.com

Output:

@            IN     A       12.34.56.789

See: The Stack Overflow Regular Expressions FAQ

Cyrus
  • 84,225
  • 14
  • 89
  • 153
0
grep -P '(^|\s)\K@(?=\s).*?\sA\s' myzonefile.com
pts
  • 80,836
  • 20
  • 110
  • 183
  • If you do not mind, can you explain why you are using both the * and the ? before the last pattern? Reading the docs, I get `. Match any single character except newline` , `* Matches the preceding element 0 or more times` , and `? Matches the preceding element 0 or 1 times`. – humbleStrength Aug 07 '23 at 16:21
  • 1
    `X*?` is like `X*`, but the former makes the match as short is possible. It's useful if you add `+(\S+)` to the regexp. By using the `?`, it will find the very first viable `A` rather than the last one. – pts Aug 07 '23 at 16:57
  • Your regex matches the lines `" @ IN A 12.34.56.789"`, `"@ IN A A 12.34.56.789"` and `"@ AN A 12.34.56.789"`. Is that intended? Note that in the first of these strings `(^|\s)` matches the last space preceding `'@'` – Cary Swoveland Aug 07 '23 at 18:25
  • Only @humbleStrength can say what is intended or them. My regexp is a working solution for the first sentence of the question. It can be fine-tuned for more specific requirements. – pts Aug 07 '23 at 18:46
  • The zone file syntax will not allow the other cases mentioned by Cary as I am executing some integrity checks on the files to ensure no formatting blunders. However, thanks for pointing that out in case something does slip by and the lines are not entered correctly, as depicted in the examples Cary showed. – humbleStrength Aug 07 '23 at 20:25
0

u mean like this ?

echo '
@            IN     SOA     some.bogus.com hostmaster.bogus.com. (
@            IN     A       12.34.56.789
             IN     A       012.345.678.9
@     1800   IN     AAAA    789237:mou68:028n:0000:8afn:
@            IN     NS      ns500.mydummy.server.
@            IN     TXT     "v=spf1 mx ~all"' | 

mawk '$1$2 == "@A"' FS='([ \t]+[0-9]*[ \t]+IN)?[ \t]+' 

@            IN     A       12.34.56.789
RARE Kpop Manifesto
  • 2,453
  • 3
  • 11
0
  • Using a single 'A' as field separator -F' A '
  • Looking for rows that start with '@' /^@/ and have two fields NF==2

$ awk -F' A ' '/^@/ && NF==2' file
@            IN     A       12.34.56.789
ufopilot
  • 3,269
  • 2
  • 10
  • 12