[英]Making A GNU-Grep-Based Script MacOS Friendly
我最近發現mutt
允許我在我的 GUI 電子郵件客戶端中做一些我多年來一直在嘗試但沒有成功的事情:(很大程度上)自動化將電子郵件消息( *.eml
)保存到我選擇的本地目錄。
這篇 Unix 和 Linux StackExchange 帖子共享了一個粗略的准備好的mutt
宏來處理這個過程。 但是,正如您將看到的,宏的grep
命令到達-P
標志(即 Perl 正則表達式),因此,不要在我當前使用的 Macbook 上運行:
#!/usr/bin/env zsh
#Saved 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"
我對復雜grep
查詢很不滿意,所以我為使這個腳本工作(例如,將-P
標志換成-e
標志)所做的微薄努力遇到了失敗。
也就是說,這是我換入-e
標志時拋出的錯誤消息:
grep: 1: No such file or directory
grep: ^Date: ?\K.*: No such file or directory
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
grep: 1: No such file or directory
grep: ^Subject: ?\K.*: No such file or directory
Error: no date parsed
Press any key to continue...
幸運的是,這里的錯誤信息非常清楚。 腳本對1
的使用似乎是錯誤的,錨定grep
查詢的最后一位也是錯誤的(例如^Date: ?\K.*
)。
不幸的是,我不知道如何開始解決這些錯誤。
事實上,我正在嘗試做的事情非常簡單。 而不是手動運行| cat > FILE_PATH/email.eml
| cat > FILE_PATH/email.eml
我希望能夠簡單地在mutt
中按下一個鍵,提取所選電子郵件的日期(例如Date:
之后的所有內容到行尾)和主題(例如所有內容到Subject
之后的行尾),然后使用該信息生成本地保存的*.eml
文件的名稱(例如 YYYY-MM-DD subject.eml)。
有沒有人對如何使這個腳本在 MacOS 中運行良好有任何建議?
一種選擇是使用zsh
參數擴展來解析值,因此無需擔心 grep 版本。 作為獎勵,這會啟動更少的子流程:
#!/usr/bin/env zsh
# Save piped email to "$1/YYMMDD SUBJECT.eml"
# Don't overwrite existing file
set -o noclobber
# stdin split into array of lines:
message=("${(@f)$(<&0)}")
mail_date=${${(M)message:#Date: *}[1]#Date: }
formatted_date=$(gdate -d"$mail_date" +%y%m%d)
# Get the subject, and change '/' to '-'
subject=${${${(M)message:#Subject: *}[1]#Subject: }//\//-}
if [[ -z $formatted_date ]]; then
print -u2 Error: no date parsed
exit 1
elif [[ -z $subject ]]; then
print -u2 Warning: no subject found
fi
outdir=${1:?Output directory must be specified}
if [[ ! -d $outdir ]]; then
print -u2 Error: no output directory $outdir
exit 1
fi
outfile="$outdir/$formatted_date $subject.eml"
print -l $message > "$outfile" && print Email saved to "$outfile"
此語句從message
中的行數組中獲取日期:
mail_date=${${(M)message:#Date: *}[1]#Date: }
${(M)...:#...}
- 從數組中獲取與模式匹配的元素。 在這里,我們使用它來查找以Date:
開頭的元素。${...[1]}
- 返回第一個匹配項。${...#Date: }
- 刪除前綴Date:
,留下日期字符串。 這個類似的語句有一個額外的擴展,將/
的所有實例替換為-
:
subject=${${${(M)message:#Subject: *}[1]#Subject: }//\//-}
zshexpn
手冊頁中記錄了參數擴展。
PS:將從寫入文件的消息中刪除尾隨換行符。 這是使用像$(...)
這樣的命令替換的一個難以避免的結果。 這不太可能是一個重大問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.