如何在Linux Shell中实现按元素分组合并文本内容?
Linux Shell下按标签分组聚合文本的实现方案
需求说明
原始输入文本:
[A] XXXX SSSS [B] EEEEE EEEEE [A] ZZZZ RRRR [B] TTTTT UUUUU [C] OOOOO ZZZZZ
期望将相同标签(如[A]、[B])下的内容聚合到一起,输出结果:
[A] XXXX SSSS ZZZZ RRRR [B] EEEEE EEEEE TTTTT UUUUU [C] OOOOO ZZZZZ
实现方案
方案一:使用Awk高效处理(推荐)
Awk是处理文本分组的理想工具,以下脚本支持按标签首次出现顺序输出:
awk ' /^\[.*\]$/ { # 记录标签首次出现的顺序 if (!seen[$0]++) keys[++count] = $0 current_key = $0 next } # 将非标签行追加到对应分组 { content[current_key] = content[current_key] $0 "\n" } END { # 按首次出现顺序输出所有分组 for (i = 1; i <= count; i++) { tag = keys[i] print tag "\n" content[tag] } }' input.txt
脚本逻辑:
- 匹配以
[开头、]结尾的标签行,记录标签的首次出现顺序,并设置当前分组键 - 非标签行直接追加到对应分组的内容中
- 处理完所有行后,按标签首次出现的顺序输出分组内容
如果不需要保持顺序,可使用更简洁的版本:
awk '/^\[.*\]$/{k=$0;next}{a[k]=a[k]$0"\n"}END{for(i in a)print i"\n"a[i]}' input.txt
方案二:纯Shell脚本(依赖基础工具)
如果仅使用Shell内置命令和基础工具(grep、sed),可采用以下脚本:
#!/bin/bash INPUT_FILE="input.txt" # 提取所有唯一标签,保留首次出现顺序 UNIQUE_TAGS=$(grep '^\[.*\]$' "$INPUT_FILE" | awk '!seen[$0]++') # 遍历每个标签,聚合对应内容 for TAG in $UNIQUE_TAGS; do echo "$TAG" # 提取当前标签到下一个标签之间的内容(排除标签行) sed -n "/^$TAG$/,/^\[.*\]$/{//!p}" "$INPUT_FILE" done
脚本逻辑:
- 用grep提取所有标签行,再通过awk去重并保留首次出现顺序
- 遍历每个标签,使用sed提取该标签与下一个标签之间的内容,排除标签行本身
内容的提问来源于stack exchange,提问作者GhislainAdon
相关产品推荐
相关产品推荐

