自動化しようとしている非常に受動的で基本的な電子メール購読キャンセルシステムがあります。サブスクリプションをキャンセルする電子メールアドレスのリストを含むファイルがあり、ファイルは1行に1つの電子メールアドレスを持つようにフォーマットされているため、catを使用すると機能するようです。
同じフォルダには、sendmailに一括送信された何千もの「.eml」ファイル(生の電子メールファイル)があります。これらの.emlファイルを作成するのは費用がかかるので、そのファイルをフォルダに保存し、誰かが購読をキャンセルするまで定期的に送信します。私が望むのは、ファイル内のすべての電子メールアドレスを繰り返し、各電子メールアドレスのフォルダからgrepを実行してから、grepに一致するファイルを削除するbashスクリプトを書くことです。
私のUnixテクノロジは非常に限られているので、Unixテクノロジを向上させるためにこれを再利用可能なbashスクリプト(ループなどを含む)にしようとしています。
答え1
簡単な方法は次のとおりです(GNUユーティリティを想定)。
grep -FZlw -f address.list -- *.eml | xargs -r0 rm -f --
または同じですが、GNUユーティリティでサポートされている長いオプションがあります。
grep --fixed-strings \
--null --files-with-matches \
--word-regexp \
--file address.list \
-- *.eml |
xargs --no-run-if-empty --null \
rm --force --
ただし、アドレスが見つかるとファイルは削除されます。どこかにファイルのFrom:
、、、、ヘッダー、または電子メールの本文または添付ファイルにありますTo:
。Cc:
Reply-To
また、から送信された電子メールもaddress.list
含まれている場合は[email protected]
削除されます。[email protected]
[email protected]
address.list
また、ファイルの電子メールアドレスが同じ形式(同じ場合はMIMEエンコードなし)であると仮定しますeml
。
たとえば、電子メールの形式が正確にどのように指定されたかを正確に知っている場合、たとえば常に次の行が1回だけ含まれている場合:
To: [email protected]
[email protected]
書式があなたの書式とまったく同じ場合は、address.list
次のことができます。
sed 's/^/To: /' address.list | grep -xZFlf - -- *.eml | xargs -r0 rm -f --
どちらがより信頼できますか?
address.list
リストに渡す代わりに性格ファイルの任意の場所を見つけるには、まずs
stream ed
itorコマンドを使用して検索リストを変換し、各行にプレフィックスを追加します"To: "
。固定文字列パターンが変更され、/ の代わりに / を使用して行 e の内容全体と一致します。 (たとえば一致しません)。To: [email protected]
-x
--line-regexp
-w
--word-regexp
x
To: [email protected]
Reply-To: [email protected].eu
ファイルを削除したくないが削除したいファイルのヘッダーを確認したい場合は、rm -f
上記のように置き換えてください。grep -H '^To:'
To:
答え2
次のスクリプトを使用します。
#!/bin/bash
email_dir=./emails
unsubscribe_file=./emails/unsubscribe.txt
while IFS= read -r email _; do
files=($(grep -rni "$email" "$email_dir" | grep -v 'unsubscribe.txt'))
if ((${#files[@]}>1)); then
printf '%s\n' "warning: Found multiple files for: $email" "${files[@]}" >&2
elif ((${#files[@]}==1)); then
rm "$(echo "${files[0]}" | awk -F\: '{print $1}')"
fi
done < "$unsubscribe_file"
email_dir
電子メールを含むディレクトリパスは、
unsubscribe_file
購読をキャンセルする電子メールを含むファイルパスに設定する必要があります。
whileループはサブスクリプションキャンセルファイルを読み取り、各行の最初のフィールドにemail
変数を設定します(このフィールドは唯一のフィールドである必要がありますが、残りのフィールドは存在する_
場合はキャプチャされます)。
その電子メールアドレスのディレクトリ内のすべてのファイルに対してgrepを実行しますemail_dir
。これにより、購読解除ファイルも返されるため、grepを使用して結果からそのファイルを削除します。同じディレクトリにない場合は理想的です。 grep -v 'unsubscribe.txt'
ただし、購読をキャンセルしたファイルの実際の名前を反映するように変更する必要があります。)
結果が複数ある場合に備えて、これらの結果を配列に設定します。この場合、エラーが発生し、何も削除されません。結果が1つだけの場合は、grep出力からファイル名を抽出して削除します。