You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用sed有条件替换文本?实现字段值标题化并保留字段名

问题描述

现有员工信息文件内容如下:

EMPLOYEE
  FIRST NAME: JOHN
  LAST NAME: DOE
  POSITION: ACCOUNT MANAGER
  
EMPLOYEE
  FIRST NAME: BIG
  LAST NAME: BOSS
  POSITION: CEO

需求如下:

  • 将字段值转换为标题大小写(单词首字母大写其余小写,多词则每个词首字母大写)
  • 保留字段名(FIRST NAME、LAST NAME、POSITION)的全大写格式
  • 保留原有缩进对齐
  • 全大写缩写(如CEO)保持原样不变

此前使用的sed命令误修改了字段名的大小写,得到错误结果:

EMPLOYEE
  First Name: John
  Last Name: Doe
  Position: Account Manager
  
EMPLOYEE
  First Name: Big
  Last Name: Boss
  Position: Ceo 

询问能否用sed实现正确需求,若可行该如何操作。

解决方案

完全可以用sed实现,核心是仅对冒号后的字段值部分处理,避免影响字段名,同时添加逻辑保留全大写缩写。

最终命令

sed -E '/^\s*(FIRST NAME|LAST NAME|POSITION):/ {
  # 拆分字段名与值,暂存字段名
  s/^(\s*(FIRST NAME|LAST NAME|POSITION):\s*)(.*)/\1/
  h
  # 提取字段值单独处理
  s/^.*:\s*//
  # 转换为标题大小写
  s/\b([A-Za-z])([A-Za-z]*)\b/\U\1\L\2/g
  # 恢复长度≤3的全大写缩写(如Ceo → CEO)
  s/\b([A-Z][a-z]{1,2})\b/\U&/g
  # 合并字段名与处理后的值
  G
  s/(.*)\n(.*:\s*).*/\2\1/
}' employees.list

命令解析

  1. 目标行匹配:/^\s*(FIRST NAME|LAST NAME|POSITION):/ 精准匹配包含目标字段的行,避免误处理其他行
  2. 拆分与暂存:
    • 用s/^(\s*(FIRST NAME|LAST NAME|POSITION):\s*)(.*)/\1/ 保留字段名(含缩进和冒号)到模式空间
    • h 将字段名存入hold空间临时保存
  3. 字段值处理:
    • s/^.*:\s*// 删除模式空间内的字段名,仅保留字段值
    • s/\b([A-Za-z])([A-Za-z]*)\b/\U\1\L\2/g 把每个词转换为标题大小写:首字母大写,其余字母小写
    • s/\b([A-Z][a-z]{1,2})\b/\U&/g 将长度为2或3的标题大小写词转回全大写,恢复CEO这类缩写的原样
  4. 结果合并:
    • G 将hold空间的字段名追加到模式空间
    • s/(.*)\n(.*:\s*).*/\2\1/ 重新组合字段名与处理后的字段值,还原原有缩进格式

执行结果

运行命令后得到符合需求的输出:

EMPLOYEE
  FIRST NAME: John
  LAST NAME: Doe
  POSITION: Account Manager
  
EMPLOYEE
  FIRST NAME: Big
  LAST NAME: Boss
  POSITION: CEO

如果不需要保留全大写缩写(所有值严格按标题大小写处理),只需去掉恢复缩写的那一行命令即可。

内容的提问来源于stack exchange,提问作者mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:48:12