2

I can use grep -Fxq search-string text-file outside of my awk, and it works they way I'd expect (found here How to test if string exists in file with Bash shell?). But, when I try to use that same grep command as an if statement inside awk, it seems to do nothing. Here's the basic usage I'm trying:

cat /var/log/somelogfile | awk '{ if (grep -Fxq $1 textfile) print "useful command $1" }'
Community
  • 1
  • 1
user1739455
  • 25
  • 1
  • 2
  • 3

4 Answers4

2

You can use awk's system function:

cat /var/log/somelogfile | awk '{ if (system("grep -Fxq " $1 " textfile")) print "useful command " $1; }'

See the docs.

djhaskin987
  • 9,741
  • 4
  • 50
  • 86
  • 1
    You should not use `cat` with program that can read data itself, like `awk`, `sed`, `perl` etc. – Jotne Jul 19 '14 at 07:31
  • 1
    Nor do you need grep when you are using awk. – Ed Morton Jul 19 '14 at 13:48
  • It looks like the `grep` may be important to what the user is trying to do. I concede the `cat` point, though. – djhaskin987 Jul 19 '14 at 17:20
  • The grep was needed to check if a username (found in column 1 by awk) existed in the text file. I am parsing the cups page log to count the number of pages printed by each user and warn them if they exceed a certain limit. I wanted to run the script once a day, but not email the same user more than once a month, hence why I needed to check if they had already been warned ie if their username had already been added to the text file. – user1739455 Jul 21 '14 at 15:34
  • Grep is a system command, not an awk command. The stuff between the single quotes are bon a fied awk language, and grep is not part of that language. So you have to rely on the actual grep program and you call programs in awk with 'system()'. Again, see the docs. – djhaskin987 Jul 22 '14 at 20:44
  • Very useful answer. In my case, I had to do `if(system("grep " $1 " textfile > /dev/null") == "0") print ...`. – Codoscope Sep 07 '17 at 16:08
1

There is no need for that, you can use anchors:

awk '/^search-string$/ {do something}'

Explanation:

  1. ^ Beginning of the line
  2. $ End of line
  3. /^search-string$/ return true if matches just like grep -Fxq

-x for grep uses anchors. I believe -F is redundant.

Tiago Lopo
  • 7,619
  • 1
  • 30
  • 51
  • That's testing for cases where a whole line matches a regexp which is completely different from testing for the existence of a string in a file as the OP is trying do do. The `-F` tells grep to look for strings instead of REs, in awk you use `index()` and `==` for that instead of `match()`, `//`, and `~`. – Ed Morton Jul 19 '14 at 13:59
1

It LOOKS like what you're trying to do is:

awk '
NR==FNR { strings[$0]; next }
{
    for (string in strings) {
        if ( index($0,string) ) {
            print "useful command", $1
            next
        }
    }
}
' textfile /var/log/somelogfile

We'll know for sure if/when you post some some sample input/output.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
0

If grep or egrep are insufficient for your text filtering, it might be easier to a perl one liner. perl offers useful command line options, like -n -e which will implicitly executes your arbitrary command inside while loop.

So for example:

  perl -ne 'if (/some line (.*)/) {print "useful command: $1\n"}' /var/log/somelogfile

will filter all the lines with "some line" text and will print everything after that text.

Jakub M.
  • 32,471
  • 48
  • 110
  • 179
  • You should not use `cat` with program that can read data itself, like `awk`, `sed`, `perl` etc. – Jotne Jul 19 '14 at 07:32
  • True, modified the command. Nevertheless, I commit this dreadful sin of `cat`ing files and then `grep`ping them since many years and I see it's drawbacks maybe once per year when I grep something *really* big. Otherwise you have nice data flow, with data source at left and filters one by one at right. Readability over performance. – Jakub M. Jul 19 '14 at 07:43