0

I want to filter the lines from the following command:

$ cat /proc/net/route
Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT                               
br-lan  01020300        C0A80101        0003    0       0       3       FFFFFF00        0       0       0                                  
br-lan  03043836        C0A80101        0007    0       0       5       FFFFFFFF        0       0       0                                  
br-lan  C0A80100        00000000        0001    0       0       0       FFFFFF00        0       0       0 

I want to extract only the line containing the Destination 01020300 and the Mask FFFFFF00

I tried with the following regexp but it does not works

cat /proc/net/route | grep "[^ \t\v]\+[ \t\v]\+$dest[ \t\v]\+[^ \t\v]\+[ \t\v]\+[^ \t\v]\+[ \t\v]\+[^ \t\v]\+[ \t\v]\+[^ \t\v]\+[ \t\v]\+[^ \t\v]\+[ \t\v]\+$mask"

I newbe wuth the regexp format. could you help me with a good regexp for this case?

MOHAMED
  • 41,599
  • 58
  • 163
  • 268

1 Answers1

5

Maybe it is easier to work with awk for this:

$ awk '$2=="01020300" && $8=="FFFFFF00"' file
br-lan  01020300        C0A80101        0003    0       0       3       FFFFFF00        0       0       0     

This way you can refer to the 2nd and 8th columns and check its value, without having to worry about the format.

In case your file separates fiels with tabs instead of spaces, use:

awk -F"\t" '$2=="01020300" && $8=="FFFFFF00"' file

And in case you want to give this values from bash variables, you can do (see comments, as Glenn Jackman, Etan Reisner and Ed Morton gave nice explanations):

awk -v d="$dest" -v m="$mask" '$2==d && $8==m' file
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • what could be the solution if my file separators could be spaces and tabs? – MOHAMED Apr 29 '14 at 16:25
  • I tried `awk -F"\t" '$2=="$dest" && $8=="$mask"' file` but it does not work – MOHAMED Apr 29 '14 at 16:28
  • For spaces and tabs you don't need to change `FS`/use the `-F` argument that's the default. – Etan Reisner Apr 29 '14 at 16:40
  • You can't use shell variables in single quoted strings so `'$2=="$dest" && $8=="$mask"'` isn't doing what you expect. If you want to use the shell variables `$dest` and `$mask` you need to use `"$2==\"$dest\" && $8==\"$mask\""`. – Etan Reisner Apr 29 '14 at 16:41
  • @MOHAMED your `awk -F` example does not work because the `awk` command is in single quotes, which means that `$dest` and `$mask` won't be interpolated by the shell. – Sigi Apr 29 '14 at 16:41
  • 1
    @EtanReisner, or use awk's `-v var=value` option: `awk -v d="$dest" -v m="$mask" '$2==d && $NF==m' file` – glenn jackman Apr 29 '14 at 18:05
  • 1
    @EtanReisner If you were going to embed the value of shell variables in your awk script then the syntax would be `'$2=="'"$dest"'" && $8=="'"$mask"'"'` but you should never do that anyway. – Ed Morton Apr 29 '14 at 18:14
  • @EdMorton An equally valid, and personally preferable, style but harder to be sure I typed correctly in this input box and harder to parse at a scan (also appears to clash with the "don't use single quotes" statement until you see what it is doing). But ultimately yeah, just don't do that. – Etan Reisner Apr 29 '14 at 18:16
  • @EtanReisner - FWIW what I showed is THE syntax to do it. The way you had it causes problems with shell positional parameter numbers being used in place of awk field numbers (think about what `$2` means in the 2 examples - in mine it's the contents of field 2 of the current input record, in yours it's the value of the 2nd positional parameter passed to your shell), having to escape other characters, etc. – Ed Morton Apr 29 '14 at 18:25
  • 1
    @EdMorton Fair enough. I wasn't thinking about needing to escape the positional parameters in that example (though I do know you have to do that). I'm more than happy to let you pick the color of this bike shed since we agree that they any color worse than not painting it in the first place. – Etan Reisner Apr 29 '14 at 18:30
  • @MOHAMED see update, and most of all see very interesting comments above this. Thanks to all commenters! – fedorqui Apr 29 '14 at 18:34
  • Thanks a lot. It works but I had to replace `$NF==m` with `$8==m` in your awk expression. may be you have to edit your question – MOHAMED Apr 30 '14 at 08:17
  • Nicd to read that, @MOHAMED . I updated to indicate so. For future references, `$NF` would mean last field (and `$(NF-1)` the penultimate and so far...). – fedorqui Apr 30 '14 at 08:59