簡體   English   中英

使基於 GNU-Grep 的腳本對 MacOS 友好

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM