0

I am trying to use different stuff with awk.
First, the use of some shell variables, which here shows how to use them.
Second, how to use a shell variable to match a pattern, which here points to use ~ operator.
Finally, I want to use some kind of or operator to match two shell variables.

Putting all together in foo.sh:

#!/bin/bash

START_TEXT="My start text"
END_TEXT="My end text"

awk -v start=$START_TEXT -v end=$END_TEXT '$0 ~ start || $0 ~ end { print $2 }' myfile

Which fails to run:

$ ./foo.sh 
awk: fatal: cannot open file `text' for reading (No such file or directory)

So I think the OR-operator (||) does not work well with regex ~ operator.
I was guessing I may need to do the OR-thing inside the regex.
So I tried these two:

awk -v start=$START_TEXT -v end=$END_TEXT '$0~/start|end/ { print $2 }' myfile
awk -v start=$START_TEXT -v end=$END_TEXT '$0~start|end { print $2 }' myfile

With same failed result.
And even this thing fails...

awk -v start=$START_TEXT '$0~start { print $2 }' myfile

So I am doing something really wrong...
Any hints how to achieve this?

nephewtom
  • 2,941
  • 3
  • 35
  • 49

2 Answers2

1

You can do the regex OR like this:

awk -v start="$START_TEXT" -v end="$END_TEXT" '$0~ start "|" end { print $2 }' myfile

awk knows the parameter passed to ~ operator is a regex, so we can just process it by insert the | or operator between two strings.

Also there's another way to pass variables into awk, like this:

awk '$0~ start "|" end { print $2 }' start="$START_TEXT" end="$END_TEXT" myfile

This will increase conciseness. But since it's less intuitive, so use it with caution.

Til
  • 5,150
  • 13
  • 26
  • 34
  • Is `$0~ start "|" end` quicker than `$0~start || $0~end` ? – nephewtom Mar 11 '19 at 19:29
  • @nephewtom I'm not sure, I think it will be a tiny bit faster. However here I mainly show a different way of using it, and it's a little bit more concise :) – Til Mar 12 '19 at 06:15
0

Well, it seems @jxc pointed my problem in the comments: the shell variables need to be quoted.

awk -v start="$START_TEXT" -v end="$END_TEXT" '$0~start || $0~end { print $2 }' myfile

That made it work!

nephewtom
  • 2,941
  • 3
  • 35
  • 49