awk: print first line of file before reading lines

14,995

Solution 1

Use the following awk script:

ps aux | awk 'NR == 1 || /PATTERN/'

it prints the current line either if it is the first line in output or if it contains the pattern.

Btw, the same result could be achieved using sed:

ps aux | sed -n '1p;/PATTERN/p'

Solution 2

If you want to read in the first line in the BEGIN action, you can read it in with getline, process it, and discard that line before moving on to the rest of your awk command. This is "stepping in", but may be helpful if you're parsing a header or something first.

#input.txt
Name    City
Megan   Detroit
Jackson Phoenix
Pablo   Charlotte

awk 'BEGIN { getline; col1=$1; col2=$2; } { print col1, $1; print col2, $2 }' input.txt

# output
Name Megan
City Detroit
Name Jackson
City Phoenix
Name Pablo
City Charlotte

Solution 3

Explaining awk BEGIN

I thought I could put it in the BEGIN section ...

In awk, you can have more than one BEGIN clause. These are executed in order before awk starts to read from stdin.

Share:
14,995
Chris Schmitz
Author by

Chris Schmitz

Application engineer at Label Insight, web dev, and maker.

Updated on June 19, 2022

Comments

  • Chris Schmitz
    Chris Schmitz almost 2 years

    How would I go about printing the first line of given input before I start stepping through each of the lines with awk?

    Say I wanted to run the command ps aux and return the column headings and a particular pattern I'm searching for. In the past I've done this:

    ps aux | ggrep -Pi 'CPU|foo' 
    

    Where CPU is a value I know will be in the first line of input as it's one of the column headings and foo is the particular pattern I'm actually searching for.

    I found an awk pattern that will pull the first line:

    awk 'NR > 1 { exit }; 1'
    

    Which makes sense, but I can't seem to figure out how to fire this before I do my pattern matching on the rest of the input. I thought I could put it in the BEGIN section of the awk command but that doesn't seem to work.

    Any suggestions?

  • Henk Langeveld
    Henk Langeveld about 10 years
    Simple solution. I think you can drop the two .* -- they just add clutter
  • Chris Schmitz
    Chris Schmitz about 10 years
    Perfect. Thanks @hek2mgl, this is exactly what I was looking for.
  • hek2mgl
    hek2mgl about 10 years
    @HenkLangeveld Yeah, this was really unnecessary clutter. Thanks for pointing this out
  • hek2mgl
    hek2mgl about 10 years
    I don't get why you mentioning the BEGIN clause in this case. Can you elaborate on this? (seems that I'm missing something)
  • Henk Langeveld
    Henk Langeveld about 10 years
    I've quoted the phrase that triggered this response now. And that was all that this question was about. Your answer deals with the core issue.