如何修改Shell脚本将匹配内容合并为单封邮件发送
如何修改脚本实现单封邮件发送所有匹配内容
我来帮你搞定这个问题!你的脚本现在每次循环都会发单独邮件,核心原因是**mailx命令被放在了循环内部**,每迭代一次就触发一次邮件发送。我们只需要先把所有要发送的内容收集起来,最后一次性发送即可。
问题分析
你当前的代码中,echo "${fields[i]}" |mailx ...这行在循环里,所以每处理一个匹配项就会发一封邮件。我们需要把内容先暂存,等所有内容都收集完再统一调用mailx。
修改方案
这里提供两种常见的实现方式,你可以根据内容量选择:
方式1:用变量收集内容(适合内容量不大的场景)
先初始化一个空变量存储邮件内容,循环中把每个匹配项追加进去,最后一次性发送:
file="/home/rkelly/Downloads/names.txt" email_content="" # 注意:原代码中read -ra names但后续用了fields,这里统一用names,若实际是fields请自行调整 while IFS=, read -ra names; do printf "%s\n" "${names[@]}" for ((i=0; i < ${#names[@]}; i++)); do srvnm=$(echo "${hostname:0:3}" | tr [a-z] [A-Z]) curdtm=$(date) subject="Hello" # 把当前匹配内容追加到邮件内容变量,加上换行保证格式清晰 email_content+="${names[i]}\n" done done < "$file" # 循环结束后,一次性发送所有内容 echo -e "$email_content" | mailx -s "$subject $curdtm" -a "$logpathfile" -r "$srvnm" "$eml01"
方式2:用临时文件收集内容(适合内容量大的场景,避免变量长度限制)
如果要发送的内容很多,用变量可能会遇到系统长度限制,这时可以用临时文件存储:
file="/home/rkelly/Downloads/names.txt" # 创建临时文件 temp_file=$(mktemp) srvnm=$(echo "${hostname:0:3}" | tr [a-z] [A-Z]) curdtm=$(date) subject="Hello" while IFS=, read -ra names; do printf "%s\n" "${names[@]}" for ((i=0; i < ${#names[@]}; i++)); do # 把当前匹配内容写入临时文件 echo "${names[i]}" >> "$temp_file" done done < "$file" # 发送邮件,读取临时文件内容 mailx -s "$subject $curdtm" -a "$logpathfile" -r "$srvnm" "$eml01" < "$temp_file" # 清理临时文件 rm "$temp_file"
额外注意点
- 原代码中
read -ra names但后续引用的是${fields[@]},这大概率是笔误,我修改时统一用了names,如果你的实际变量是fields,记得替换回来。 - 邮件主题里的
$curdtm如果需要是邮件发送时的时间,建议把curdtm=$(date)放在循环外面,避免每次循环都更新时间(当然如果要的是处理时的时间可以保留在循环里)。 - 确保
$logpathfile、$eml01这些变量已经正确定义,避免发送失败。
内容的提问来源于stack exchange,提问作者kume8sit
相关产品推荐
相关产品推荐

