Saving email as file in mutt?

When I press S in mutt, it saves the mail to a mail folder format (cur/ tmp/ new/), but I want a single file to be saved, just like how attachments are saved.

Is that configurable?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The s command saves to a mailbox, which for you is in maildir format. Unfortunately, there is no save-to-file command, perhaps because in the historical mbox format, a mailbox that contains a single mail is just a file containing that mail.

The mutt command pipe-message (default shortcut |) can be used for this. It opens a command line and you write cat > DESIRED-FILE-PATH.

The “pipe-decode” option controls what happens to headers and mime parts when you save a message this way.

One could probably write a macro for this functionality.

Method 2

The actual message shows up as an attachment as well, so you can save it from the attachment list. From either the index or the message itself, hit v to open the attachments and s to save

Method 3

If you touch a file and then try to save or copy a message to it mutt will use it as a mbox.

Also you might want to use copy instead of save. Mutt assumes that a mail should only exist in one copy and saving a message to another mailbox will delete it from the first one, while copying will do a proper copy.

Method 4

Kai von Fintel‘s answer works perfectly, but I just thought I’d share a macro to streamline this process.

Firstly, in muttrc:

macro index,pager S "| ~/.local/bin/file_email /tmp<enter>"

This pipes the full email (including headers and attachments) to the following script. Create an executable file at ~/.local/bin/file_email.

#!/usr/bin/env bash
# Save piped email to "$1/YYMMDD SUBJECT.eml"

# Don't overwrite existing file
set -o noclobber

message=$(cat)

mail_date=$(<<<"$message" grep -oPm 1 '^Date: ?K.*')
formatted_date=$(date -d"$mail_date" +%y%m%d)
# Get the first line of the subject, and change / to ∕ so it's not a subdirectory
subject=$(<<<"$message" grep -oPm 1 '^Subject: ?K.*' | sed 's,/,∕,g')

if [[ $formatted_date == '' ]]; then
  echo Error: no date parsed
  exit 1
elif [[ $subject == '' ]]; then
  echo Warning: no subject found
fi

echo "${message}" > "$1/$formatted_date $subject.eml" && echo Email saved to "$1/$formatted_date $subject.eml"

This script saves the file to the first argument (i.e. in the muttrc example above, the email will save to /tmp). The format of the file name is YYMMDD SUBJECT.eml. It also converts / to to prevent creating subdirectories.

Method 5

I have tried all the suggested answers but could not get the raw, multipart (text/plain + text/html) e-mail to be saved to a file, including it’s headers and everything. I needed this to feed my spam-filter with the e-mail to teach it, that a specific mail is spam or not…

The solution I came up with is pressing e (i.e. “edit message”) on the open message, which opens the raw message in your editor of choice. Raw here means, that you get the message exactly as it arrived in mutt, so you have all the headers and all the bytes that comprise the message.

After hitting e, I just write the buffer (I set editor to vim) to a file with :w <path_to_file>/<file_name> and that’s it.

P.S: I would have added this as comment but you need a certain level of reputation to do this. Also, I know the question is very old but as neomutt is still used by many people, I thought this might help someone.

Update: I overlooked the pipe-decode option that Kai was talking about. With that option set correctly it would have worked via |, too. Still my solution is working, too 😉


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments