Bash技术问题:读取文本至末尾并按指定单词分割内容
按'END'分割文本并处理内容的解决方案
嘿,我看你现在的问题是没法用END作为标记分割你的RECORD文本,原代码的问题在于它默认按换行符读取内容,但你的目标文本是连续的字符串,没有换行,所以完全没触发你想要的分割逻辑。我给你两种实用的解决方案,你可以根据需求选:
方案一:用awk一步到位分割+处理
awk可以直接把END设为记录分隔符,这样能自动把文本拆分成你要的几段,还能顺便完成字段提取和后续操作,代码简洁高效:
# 先定义你的RECORD内容 RECORD="ijj%%% klfklk @ ; kjkjkdjjd 333 ; jkjdkj@kjk.com ; END ijj%%% klfklk @ ; kjkjkdjjd 333 ; jkjdkj@kjk.com ; END kjkjlsj ; popo ; END" echo "$RECORD" | awk -v RS='END' 'NF>0 { # 先去除这段内容首尾的多余空格 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $0) # 用;(前后可能带空格)拆分出邮箱、主题、正文 split($0, parts, /[[:space:]]*;[[:space:]]*/) email=parts[1] subject=parts[2] body=parts[3] # 这里先打印测试,确认内容正确后再替换成你的mail命令 printf "处理第%d段:\n 邮箱: %s\n 主题: %s\n 正文: %s\n\n", NR, email, subject, body # echo "$body" | mail -s "$subject" "$email" }'
这段代码的关键点:
-v RS='END':告诉awk把END当作每条记录的分隔符,自动拆分文本NF>0:过滤掉最后可能出现的空记录(因为原文本结尾是END)split函数:灵活处理;前后可能带空格的情况,避免拆分出空字段
方案二:纯Bash字符串拆分处理
如果你更习惯用原生Bash语法,也可以先把文本拆成数组,再逐段处理:
RECORD="ijj%%% klfklk @ ; kjkjkdjjd 333 ; jkjdkj@kjk.com ; END ijj%%% klfklk @ ; kjkjkdjjd 333 ; jkjdkj@kjk.com ; END kjkjlsj ; popo ; END" # 把所有END替换成换行,再读入数组 IFS=$'\n' read -r -d '' -a split_segments <<< "$(echo "$RECORD" | sed 's/END/\n/g')" # 遍历每一段处理 segment_count=1 for seg in "${split_segments[@]}"; do # 跳过空的段落 [[ -z "$seg" ]] && continue # 去除段落首尾的空格 trimmed_seg=$(echo "$seg" | xargs) # 按;拆分字段,再分别去除每个字段的空格 IFS=';' read -r raw_email raw_subject raw_body <<< "$trimmed_seg" email=$(echo "$raw_email" | xargs) subject=$(echo "$raw_subject" | xargs) body=$(echo "$raw_body" | xargs) # 打印测试,确认后替换mail命令 printf "split %d = %s\n" "$segment_count" "$trimmed_seg" # echo "$body" | mail -s "$subject" "$email" ((segment_count++)) done
原代码为啥不行?
你原来的while read line是按换行符读取内容,但你的RECORD是一整串没有换行的文本,所以read只会把整个内容当成一行,完全没触发按END分割的逻辑。所以核心是要把END作为分隔符,而不是依赖换行。
内容的提问来源于stack exchange,提问作者Java Team
相关产品推荐
相关产品推荐

