117

My dummy file looks like this:

C1    C2    C3    
1     a     snow   
2     b     snowman 
snow     c     sowman

I want to get line if there is string snow in $3. I can do this like this:

awk '($3=="snow" || $3=="snowman") {print}' dummy_file

But there should be more simpler way.

pogibas
  • 27,303
  • 19
  • 84
  • 117

5 Answers5

211
awk '$3 ~ /snow/ { print }' dummy_file 
Gordon
  • 312,688
  • 75
  • 539
  • 559
Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58
  • 42
    strictly speaking, the print isn't needed: `'$3~/snow/'` suffice – SheetJS Jun 08 '13 at 20:40
  • 2
    Sadly that link is already dead: Here is the current link http://shop.oreilly.com/product/9781565924277.do – Stedy Feb 11 '15 at 22:37
  • Your pattern is "snow", while if there's special symbol, like [ \ " in my case, the index() is a better solution. – Qiu Yangfan Jun 24 '15 at 07:58
  • Is there an way to negate the check? I know we can use 'next' instead of 'print' and print everything else, but just checking for something with fewer instructions – Sahas Jun 28 '16 at 09:51
  • 5
    use ! so e.g. awk '$3 !~ /foo/' – Ahmed Masud Jun 30 '16 at 06:50
  • 2
    How to print the line number of the matched string. I mean, suppose /String/ is located in line 80, I want to get the line number. Thanks. – Shicheng Guo May 13 '17 at 23:29
  • 2
    {print NR,$0} will print the "record/line number" and the whole line matched. Caveat, assuming you only passed one filename to awk. If you give a list of files as arguments to your awk command, you would want to make sure you are using GNU awk, and change NR to FNR to get the correct line number. – Daniel Liston Sep 16 '17 at 00:09
  • as an aside while @SheetJS is correct that `{ print }` is not needed, i originally put it in there to show where the "operational part" would go because `$3 ~ /snow/` syntax may unfamiliar to a new user and they may confuse it with "operation" rather than pattern matching part of awk. – Ahmed Masud Jul 20 '21 at 19:32
54

Also possible by looking for substring with index() function:

awk '(index($3, "snow") != 0) {print}' dummy_file

Shorter version:

awk 'index($3, "snow")' dummy_file
Thunderbeef
  • 1,471
  • 1
  • 13
  • 17
12

Maybe this will help

http://www.math.utah.edu/docs/info/gawk_5.html

awk '$3 ~ /snow|snowman/' dummy_file
Ahmed Al Hafoudh
  • 8,281
  • 1
  • 18
  • 34
10

Print lines where the third field is either snow or snowman only:

awk '$3~/^snow(man)?$/' file
Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
1

GNU sed

sed '/\s*\(\S\+\s\+\)\{2\}\bsnow\(man\)\?\b/!d' file

Input:

C1    C2    C3    
1     a     snow   
2     b     snowman 
snow     c     sowman
      snow     snow     snowmanx

..output:

1     a     snow
2     b     snowman
Community
  • 1
  • 1
Endoro
  • 37,015
  • 8
  • 50
  • 63
  • 13
    This could not be a more complicated answer to a pretty straight forward question. – Sam Jul 23 '14 at 20:44
  • 1
    Plus, it is VERY risky to use `sed` for whole words. Albeit technically possible, for that to work reliably, I had to use look-behind, look-forward as well as `!?` constructions when it was about words that should *not* follow. This is nothing for the faint of heart, that's for sure. (And prone to errors that might consume plenty of time to find and fix them.) – syntaxerror Oct 11 '14 at 13:47