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

sed脚本替换CSV第五字段内小于100数字为字符串的问题

问题:用sed替换CSV第五字段中小于100的数字为"none"

需通过sed脚本将逗号分隔的CSV文件第五字段中小于100的数字替换为"none",现有脚本错误替换了大数字的开头部分,且要求不能使用awk。

示例CSV

datetime,car,brand,model,km,new
10/10/1949 20:30,yes,ford,f150,20,yes
10/10/1949 20:30,no,yamaha,r7,1560,yes
10/10/1949 20:30,yes,renault,twingo,37,yes
10/10/1949 20:30,no,honda,cbr600rr,2000,no

现有错误脚本

# Replace
s/\([^,]*,[^,]*,[^,]*,[^,]*\,\)\(0\|[1-9][0-9]\{0,1\}\)\([^,]*\)/\1none\3/

执行命令

sed -f script.sed ./sample.csv

期望输出

datetime,car,brand,model,km,new
10/10/1949 20:30,yes,ford,f150,none,yes
10/10/1949 20:30,no,yamaha,r7,1560,yes
10/10/1949 20:30,yes,renault,twingo,none,yes
10/10/1949 20:30,no,honda,cbr600rr,2000,no

实际错误输出

datetime,car,brand,model,km,new
10/10/1949 20:30,yes,ford,f150,none,yes
10/10/1949 20:30,no,yamaha,r7,none60,yes
10/10/1949 20:30,yes,renault,twingo,none,yes
10/10/1949 20:30,no,honda,cbr600rr,none00,no

问题原因

原脚本的正则仅匹配了第五字段中数字的开头1-2位(比如1560中的15),后续的[^,]*会保留剩余字符,导致替换后出现none60这类错误结果。核心是没有限定匹配的数字必须是整个第五字段的内容,即数字后必须紧跟逗号或行尾。

修正后的脚本

# Replace fifth field (km) with "none" if value is <100
s/\([^,]*,[^,]*,[^,]*,[^,]*,\)\([0-9]\{1,2\}\)\(,\|$\)/\1none\3/

正则解释

  • \([^,]*,[^,]*,[^,]*,[^,]*,\):精准匹配前四个字段及末尾的逗号,捕获为分组1
  • \([0-9]\{1,2\}\):匹配1-2位数字(0-99),捕获为分组2
  • \(,\|$\):匹配第五字段后的逗号或行尾,确保匹配的是整个字段的数字,捕获为分组3
  • 替换逻辑:将分组2的内容替换为none,保留分组1和分组3的原始内容

如果需要排除以0开头的两位数(比如05这类无效数字,仅保留0和1-99的有效数字),可调整正则为:

s/\([^,]*,[^,]*,[^,]*,[^,]*,\)\(0\|[1-9][0-9]\?\)\(,\|$\)/\1none\3/

验证结果

执行原命令后,输出与期望输出完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:01:32