34

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?

5 Answers 5

39

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.

5
  • Cool, this can save the headers as well, but for now, I'd use Michael's way, thanks! Commented Jan 11, 2013 at 1:56
  • 1
    This works well and provides an efficient manner of saving 50+ emails (using pattern-matching tagging) to file. I had to dig a little to find that by adding set pipe_decode=yes to my muttrc was what Kai von Fintel was writing about. Commented May 1, 2015 at 13:36
  • also, this saves the attachments in the exported email file, as well. Commented May 19, 2015 at 10:55
  • this is fine, but i see un-processed line breaks with = doing this. Commented Aug 23, 2019 at 11:18
  • Awesome. This worked great for me. I just wanted to extract some 20+ emails from an obsolete Maildir. Cheers! Commented Sep 3, 2019 at 0:46
34

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

5
  • Just a note: if your email message contains attachments, then saving just the first entry from the attachments list will save the message - but without the attachments included inside. Commented May 19, 2015 at 10:02
  • 8
    Another note: this doesn't save any headers, including sender, recipient and subject. Commented Oct 11, 2015 at 3:35
  • @Sparhawk It does save the headers but you have to press h to show them, first... Commented Nov 27, 2023 at 13:54
  • @m4110c That doesn't seem to work for me. In addition, I can always see some headers, and h just shows all the headers. Either way, the headers aren't saved. Commented Nov 27, 2023 at 21:14
  • @Sparhawk You're right, my bad. I just tested it and the headers are not saved this way. I guess the best way would be to go with the | key and use a linux command to store the mail, as described in the answer of Kai von Fintel. Also setting the set pipe_decode=yesshould not be omitted in the .muttrc Commented Nov 28, 2023 at 12:59
13

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.

1
  • 1
    I needed to get the message with the full headers to paste it into a filter test script, and this worked perfectly. Commented Aug 15, 2016 at 14:56
7

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.

2
  • Wouldn't be easier to use formail in the script? Commented Jan 11, 2019 at 14:05
  • @0andriy I'm not familiar with formail, so I had a read. However, I'm not entirely sure which part of my script you were referring to? Using formail to extract subject and date? If so, probably a nice idea. I'd urge you to write an answer; I'd definitely upvote it. Commented Jan 14, 2019 at 0:30
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 ;-)

4
  • Any solution if mailbox is read-only? Commented Nov 16, 2023 at 12:00
  • @OlleHärstedt You should go with the answer provided by Kai von Fintel. Don't forget the set pipe_decode=yes in your .muttrc however. Commented Nov 28, 2023 at 13:01
  • No matter how I set pipe-decode, it strips the headers from the raw multipart. Your e solution is the only thing that works for me. Commented Jul 31 at 7:08
  • Just figured it out. exec pipe-message from the message list and |:Pipe from the message viewer are not the same. The former obeys pipe_decode, the latter does not. Commented Jul 31 at 7:10

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.