4

Lets say I have 5 messages in /var/mail/ and I want to read one message at a time and then do some string search in that mail before moving on to the next message. Is there a command that I can use to parse one message at a time ?

I am looking to write a bash script which will read all messages in an mbox file & then read them one at a time so that I can then extract Subject, To, From & Status of the message(bounceback code). My plan was to use grepmail to get count of emails in the file and then use this count in a for loop to get one mail at a time and them perform operation on the text. Something like:

$count = grepmail -r . /var/mail/user | awk '{print $2}'
for($i=1;$i<=$count;$i++) {
    $content = *GetMessage* -number $i /var/mail/user
    ...
    Do string operation on this message & save to $DelimitedData
    ...
}
$Delimiteddata

I can't figure out how to pickup single message at a time to perform string operation on them. Can someone please guide me which command/program can help me do this non interactively.

4
  • 1
    I'm guessing you mostly work with powershell?
    – jesse_b
    Aug 9, 2019 at 19:11
  • @Jesse_b Yes I mostly script in powershell. I have a script that does exactly what I want, but we are moving to a linux box for some of the emails and I want to make sure that I get the reports.
    – OjasP
    Aug 9, 2019 at 19:16
  • You can install powershell on linux, but hopefully someone can also help you with a shell solution as it will be faster.
    – jesse_b
    Aug 9, 2019 at 19:20
  • @Gilles formail answer is good, but it's also worth knowing that the "beginning of message" marker in an mbox format file is a line beginning with From ("From" and a space character). This can reliably be used to split mbox files into individual messages, with the regexp ^From as it is guaranteed NOT to be within the headers or body of the message (any body lines that would have started with "From " are changed when saved into an mbox, usually to ">From " or similar). See en.wikipedia.org/wiki/Mbox
    – cas
    Aug 10, 2019 at 1:24

1 Answer 1

11

The formail tool from procmail (available in any distribution, it's a classic) is designed precisely for this purpose.

Basic usage:

formail -s myprogram --option

runs myprogram --option on each mail in turn. The program receives each mail on its standard input.

5
  • Not sure that formail can pick up the Nth message in an existing spool file, though Can it? Aug 9, 2019 at 23:10
  • @roaima I don't think it's needed (the OP had that loop because they didn't know how to process messages in an mbox one-by-one), but formail has a +skip option, and a -total option (the "skip" in the +skip is the number of messages to skip, and the "total" in -total is the total number of msgs to output - so +5 -1 would output only the 6th message).
    – cas
    Aug 10, 2019 at 1:15
  • Thanks for the comment @Gilles. I can't figure out how to use the stream from formail in a shell script. In my test script I am just reading input from formail -s command & displaying it but i don't get any output & the script waits until I press Ctrl+C. Here's my script: #!/bin/sh print $1 read -p message </dev/tty echo "${message}" I am calling it by formail -s test.sh -d
    – OjasP
    Aug 12, 2019 at 13:56
  • 1
    @OjasP formail reads from standard input, so e.g. formail </var/mail/bob -s test.sh Aug 12, 2019 at 14:01
  • Thanks @Gilles! For someone else who stumbles across this, I used this command: formail -s </var/mail/user ./test.sh . And, in the test.sh file I am reading the message using message=$(</dev/stdin)
    – OjasP
    Aug 12, 2019 at 16:24

You must log in to answer this question.

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