Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

combine multiple awk commands

Tags:

awk

Assuming the following input:

$ cat example
{many lines of text}

Col1 Col2  Col3
foo  bar   2 
bar  baz   3
baz  bar   8
bar  foo   0
foo  baz   9
baz  bar   3

{many more lines of text}

The following two awk snippets parse out the data I'm after:

cat example | awk -v 'RS=\n\n' '/^Col1 /' | awk '$2 == "bar" && $3 > 1 {print $1}'
foo
baz
baz

How do I combine the two snippets into a single bit of awk, e.g.

awk '
...
...
...
' example
like image 649
user145664 Avatar asked Aug 28 '12 20:08

user145664


People also ask

How do you match patterns with awk?

Any awk expression is valid as an awk pattern. The pattern matches if the expression's value is nonzero (if a number) or non-null (if a string). The expression is reevaluated each time the rule is tested against a new input record.

What awk $2?

awk '{ print $2; }' prints the second field of each line. This field happens to be the process ID from the ps aux output. xargs kill -${2:-'TERM'} takes the process IDs from the selected sidekiq processes and feeds them as arguments to a kill command.

What is awk NF?

NF is a predefined variable whose value is the number of fields in the current record. awk automatically updates the value of NF each time it reads a record. No matter how many fields there are, the last field in a record can be represented by $NF . So, $NF is the same as $7 , which is ' example.


3 Answers

You can do:

awk '/^Col1 /,/^$/{ if( $2 == "bar" && $3 > 1 ) print $1}' example
like image 82
William Pursell Avatar answered Oct 01 '22 15:10

William Pursell


This seems to work.

gawk '/^$/{getline;if(/^Col1/){doit=1}else{doit=0;}} doit && $2=="bar" && $3>1 {print $1}' example

Broken into readable chunks with comments, this is:

/^$/ {                      # Look for a blank line
  getline;                  # Get the next line
  if (/^Col1/) {            # See if your column heads exist.
    doit=1                  # If they do, set a boolean to true
  } else {
    doit=0;                 # Otherwise, false.
  }
}

doit && $2=="bar" && $3>1 { # Check the boolean AND your conditions, then
  print $1                  # print.
}
like image 27
ghoti Avatar answered Oct 01 '22 13:10

ghoti


Use a flag, set it when found "Col1" as first column and reset it when found a blank line after setting it. Between that, check for the condition of your last pipe:

awk '
    $1 == "Col1" { 
        block = 1; 
    } 
    block == 1 && $2 == "bar" && $3 > 1 { 
        print $1; 
    } 
    block == 1 && $0 ~ /^[[:blank:]]*$/ { 
        exit 0; 
    }
' infile

Output:

foo
baz
baz
like image 44
Birei Avatar answered Oct 01 '22 15:10

Birei