0

I have a file where the 2nd column looks like this:

37M533N38M
14M1170N45M233N16M
3S45M3N35M

I want to extract those strings which contain 3N but no other numbers immediately before the 3. So, for example, A3N would match but 23N would not. It should also be noted that 3N would never be present alone and the string will not start with 3N and will not end with 3N. The result should be the third line from the above:

3S45M3N35M

How can I do it in awk? I have tried $2 ~ /3N/ but that certainly doesn't work.

5

You can use a negated character class: [^0-9] means "any character except a digit":

awk '$2~/[^0-9]3N/' file

If you also want to match cases where the 3N is at the very beginning of the field so there are no characters before it, use:

awk '$2~/(^|[^0-9])3N/' file

If you only want to print the second field and not the whole line, use:

awk '$2~/[^0-9]3N/{print $2}' file

or

awk '$2~/(^|[^0-9])3N/{print $2}' file
  • For the second case you describe, you could also just use: awk '($2 ~ /3N/) && ($2 !~ /[0-9]3N/)' – Wildcard Feb 17 '17 at 21:54
  • @Wildcard why would I want to use two tests where one would do? – terdon Feb 17 '17 at 21:55
  • You wouldn't. But I thought it worth noting in the comments for pedagogical simplicity. – Wildcard Feb 17 '17 at 22:14
  • Why do you put a + after the [^0-9]? – G-Man Feb 17 '17 at 22:22
  • @G-Man Um, because I had originally used * which is of course wrong, and just changed it to + without realizing I didn't actually need anything at all. In my defense, it's late here. – terdon Feb 17 '17 at 22:39
0

Using grep:

grep [^0-9][3][N] file

v - to show those that don't match / invert match

[0-9][3][N] - pattern to find 3N with a positive integer preceding.

  • 2
    Why the [3]? There's not much point in using a character class for a single character. Also, you could do this in one go with grep -E '[^0-9]+3N' file. – terdon Feb 17 '17 at 21:28
  • Yes, agree. That is a better approach for sure. – GC 13 Feb 17 '17 at 21:29
  • 1
    @terdon Well, yes he could, but he forgets to match only in the second column. – Kusalananda Feb 17 '17 at 21:29
  • 1
    @Kusalananda ah yes, true. I guess you could do something like grep -E '^\S+\s+\S+[^0-9]+3N' file then. Or, to get only the second field (and assuming GNU grep): grep -Po '^\S+\s+\K\S+[^0-9]+3N\S+' file. – terdon Feb 17 '17 at 21:32
  • @terdon: Even that approach won't work correctly (it might pick up the third, fourth, fifth, or ... etc., column) unless you anchor it with ^. – G-Man Feb 17 '17 at 22:19
0

Tested with below command and it worked fine for above example

awk '$2 ~ /[A-Za-z]3N/{print $0}' filename

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.