1

"Issue"... The command is doing what is actually instructed to.

Given this mbox format file:

From: [email protected] #identifies the beginning of the first mail    
...
Subject: crcheck.sh #identifies the beginning of the mail body
...
MYVARIABLE="123"
...
From: [email protected] #identifies the beginning of the next mail
...
Subject: crcheck.sh #identifies the beginning of the mail body
...
From: [email protected] #identifies the beginning of next mail
...
Subject: crcheck.sh #identifies the beginning of the mail body
EVILVARIABLE="0.00" #just to mention a value that would cause division by zero errors and crash my main script.
...
From: [email protected] #identifies the beginning of the next mail
...

I need to select all lines between a valid Subject: and the next From:, but the From: preceiding the Subject line should be the $GOODSENDER one.

The code I'm running:

GOODSUBJECT="crcheck.sh"
GOODSENDER="[email protected]"
cat $MBOX |awk "/Subject\: $GOODSUBJECT$/{a=1}/From\:\ $GOODSENDER /{print;a=0}a"|grep $i\=\"

Outputs:

MYVARIABLE="123"
EVILVARIABLE="0.00"

Expected output:

MYVARIABLE="123"

The command is doing what it's instructed to, as those lines are acutally between two of the lines I set as patterns for awk.

But how can I adjust it to have this desidered behaviour?

4
  • I don't see "crcheck.sh" subject in your input. Will you update the input? Commented Sep 15, 2017 at 19:24
  • TY for your attention, it's everywhere. I edited the question.
    – Marco
    Commented Sep 15, 2017 at 19:27
  • some kind of duplicate stackoverflow.com/questions/46245806/… Commented Sep 15, 2017 at 19:56
  • TY sir, the other post on SO turned into a best practice coding contest, and it was probably my fault, because the question was all about this single awk line. I'm going to delete the SO one, as soon as the guy telling me that the error was all about my bad coding practices will reply. :)
    – Marco
    Commented Sep 15, 2017 at 20:01

1 Answer 1

2

Try:

$ awk "/Subject:/{a=0} /From:/{a=0; b=0} a && b && /MYVARIABLE=/{print} /Subject: crcheck.sh$/{a=1} /From: [email protected]/{b=1}" mbox
MYVARIABLE="123"

How it works

  • /Subject:/{a=0} /From:/{a=0; b=0}

    When we reach a subject or from line, turn all flags false.

  • a && b && /MYVARIABLE=/{print}

    If both flags are true and the line includes the string MYVARIABLE=, then print the line.

  • /Subject: crcheck.sh$/{a=1}

    If the subject line is good, set flag a to true.

  • /From: [email protected]/{b=1}

    If the from line is good, set flag b to true.

Notes

  1. It is poor practice to use all caps for shell variables. The system use all caps for its variables and you don't want to accidentally overwrite one of them.

  2. cat is unneeded. Awk takes file names as arguments.

  3. In regexes, : and space are not special. They don't need to be escaped.

  4. In email headers, Subject: and From: are both supposed to start at the beginning of the line. A better regex for each might be /^Subject:/ and /^From:/ where ^ is the regex symbol for start-of-line.

Passing a variable to awk

$ var=MYVARIABLE
$ awk -v x="$var" '/Subject:/{a=0} /From:/{a=0; b=0} a && b && $0 ~ (x"="){print} /Subject: crcheck.sh$/{a=1} /From: [email protected]/{b=1}' mbox
MYVARIABLE="123"

Sample Input

The output above was generated using this as the input file:

$ cat mbox
From: [email protected]
...
Subject: crcheck.sh
...
MYVARIABLE="123"
...
From: [email protected]
...
Subject: crcheck.sh
...
From: [email protected]
...
Subject: crcheck.sh
EVILVARIABLE="0.00"
...
From: [email protected]
...

This is the same as in the question except that, to restore it to mbox format, the added comments have been removed.

13
  • this won't print anything on the OP's input: ibb.co/fXxSPQ Commented Sep 15, 2017 at 19:54
  • @RomanPerekhrest The OP's "input" has comments. From the question, it was clear that the comments weren't in the input he was testing with. So, I removed the comments. With comments removed, the code produces for me exactly the output that I show. I will update the answer showing the input I use.
    – John1024
    Commented Sep 15, 2017 at 19:57
  • there's no output for me too! user@host:~$ cat /var/mail/user |awk "/Subject:/{a=0} /From:/{a=0; b=0} a && b{print} /Subject\: $/{a=1} /From: [email protected]/{b=1}" user@host:~$
    – Marco
    Commented Sep 15, 2017 at 20:36
  • 1
    @Marco OK. There are two reasons for that. (1) The code that you are testing is different from my code. Your code includes the command /Subject\: $/{a=1} which will only trigger if the subject line consists of a single space. This likely never happened in your file. (2) I can't debug the output from your /var/mail/user file since I don't know what is in it. While we are debugging, please use the sample input from the question (but with the comments removed as shown in my answer). Thanks.
    – John1024
    Commented Sep 15, 2017 at 20:43
  • 1
    TY very much for your extra hints, too!
    – Marco
    Commented Sep 16, 2017 at 6:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .