A command-line utility to parse .eml files. It extracts email metadata into a structured JSON file,
saves the plain text and HTML bodies, and dumps all file attachments into the specified directory.
-
Metadata Extraction: Parses core email headers (From, To, Subject, Thread-Topic, Date, CC, Delivered-To) and saves them in
meta.json. -
Body Separation: Extracts and decodes
text/plainandtext/htmlparts into dedicatedbody.txtandbody.htmlfiles. -
OS-Safe Attachment Downloader: Saves all email attachments using a strict filename sanitization pipeline.
-
Bulk Processing (
Bash): Recursively scans directories for.emlfiles, and packs results into a.tgzarchive.
Why Bash? That's one of life's greatest mysteries.
- Python 3.10 or higher (dataclass
slotssupport) - Bash 3.2 or higher
Run the script from your terminal by providing the path to the .eml file and the directory where the extracted
contents will be saved:
python main.py emails/invoice.eml output/parsed_invoiceOnce executed, the tool organizes the parsed email components within the output directory as follows:
output/parsed_invoice/
├── meta.json # Extracted headers and attachment mapping
├── body.txt # Text body
├── body.html # HTML body with localized attachment paths
└── [attachment_files] # Sanitized attachment files (e.g., report.pdf, logo_1.png)
Make the script executable:
chmod +x parse_bulk.shRun the bulk script from your terminal by providing the path to the directory where the .eml files are located:
./parse_bulk.sh /path/to/emails_directoryOnce executed, the bulk script creates an isolated, timestamped archive and an execution log file alongside your target folder:
/path/to/
├── emails_directory/ # Your source folder (untouched)
└── emails_directory_output_20260611_181722.tgz # The resulting parsed data archive
└── emails_directory_output_20260611_181722.log # Full process log
Inside the archive, every email gets its own dedicated subfolder containing its meta.json, body.txt, body.html,
and attachments.
To run this parser from any directory in your OS without typing the full path to main.py, you can set up a command
alias.
-
Open your shell configuration file in a text editor:
nano ~/.zshrc(Use
~/.bashrcif you are using Bash instead of Zsh) -
Add the following line at the bottom of the file, replacing the path with the actual absolute paths:
# Shortcut for single file parser alias eml-parser="python3 /absolute/path/to/your/project/main.py" # Shortcut for the bulk parser alias eml-bulk-parser="bash /absolute/path/to/your/project/parse_bulk.sh"
-
Save the file, exit the editor, and reload the configuration:
source ~/.zshrc
Parse one file inside Downloads:
cd ~/Downloads
eml-parser ./incoming_emails/sample.eml ./extracted_dataParse a folder inside Downloads:
cd ~/Downloads
eml-bulk-parser ./incoming_emails