Skip to content
Advertisement

Grep a line then print awk until a certain substring

My code is

var=$(cat $FILE | grep "$alineimlookingfor" | awk '{print $1, $2, $4, $7, $9... all the way to $20}'
echo "$var" 

But, I want to have $9-$20 be stopped when it hits a value like (0) or (1). This will make my output format and look a lot nicer because anything after (0) or (1) is garbage.

Does anyone have an idea on a way to implement that?

Input:

2013-02-21 00:12:03,374 [Thread] IN ProcedureTask - Finished Sales Summary 22 This (0) - 21-JUNE-10    

Output:

2013-02-21 00:12:03,374 IN ProcedureTask - Finished Sales Summary 22 This (0)

EDIT: THANK YOU TO ALL THE PEOPLE THAT COMMENTED ON THIS THREAD ESPECIALLY ED AND GLENN

Advertisement

Answer

Update:

awk -v pattern="$alineimlookingfor" '
    $0 ~ pattern {
        rec = $1 OFS $2 OFS $4 OFS $7
        for (i=9; i<=NF; i++) {
            rec = rec OFS $i
            if ($i ~ /([01])/) {
                break
            }
        }
        print rec
    }
' "$FILE"

Should meet your requirements exactly

Notes:

  • NF is an awk variable containing the Number of Fields in the current record.
  • when we see a record that contains the pattern:
    • store the first 4 fields in a variable called rec, separated by the Output Field Separator.
    • loop over the fields from 9 to the last, appending to the rec variable
      • when we see one that matches the regular expression (a zero or a one in parentheses), then we break out of the for loop
    • and print the accumulated rec string.

First of all, be aware that awk can do what cat and grep do, so we can simplify the pipeline immediately

awk -v pattern="$alineimlookingfor" '$0 ~ pattern {print $1, $2, $4, $7, $9... all the way to $20}' "$FILE"

Next, it sounds like you want to

awk -v pattern="$alineimlookingfor" '
    $0 ~ pattern {
        for (i=9; i<NF; i++) {
            if ($i == "(0)" || $i == "(1)") {
                NF = i
                break
            }
        }
        print
    }
' "$FILE"

This changes the “number of fields in this record” variable, so that subsequent fields are ignored.

Testing

alineimlookingfor=ProcedureTask
awk -v pattern="$alineimlookingfor" '
    $0 ~ pattern {
        for (i=9; i<NF; i++) {
            if ($i == "(0)" || $i == "(1)") {
                NF = i
                break
            }
        }
        print
    }
' <<'END'
foo
2013-02-21 00:12:03,374 [Thread] IN ProcedureTask - Finished Sales Summary 22 This (0) - 21-JUNE-10    
bar
2013-02-21 00:12:03,374 [Thread] IN ProcedureTask - Finished Sales Summary 22 This (1) - 21-JUNE-10    
baz
2013-02-21 00:12:03,374 [Thread] IN ProcedureTask - Finished Sales Summary 22 This (2) - 21-JUNE-10    
END

Outputs

2013-02-21 00:12:03,374 [Thread] IN ProcedureTask - Finished Sales Summary 22 This (0)
2013-02-21 00:12:03,374 [Thread] IN ProcedureTask - Finished Sales Summary 22 This (1)
2013-02-21 00:12:03,374 [Thread] IN ProcedureTask - Finished Sales Summary 22 This (2) - 21-JUNE-10    
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement