使用sed脚本执行正则时无法实现指定姓名大写的问题
问题:Sed脚本中姓名大写替换规则不生效的原因
我编写了如下.sed脚本:
# replace female-male with F-M s/female/F/ s/male/M/ # capitalize the name when the sport is volleyball or taekwondo s/^([^,]*,)([^,]+)((,[^,]*){5},(volleyball|taekwondo),)/\1\U\2\L\3/
同时有如下CSV文件(前10行):
id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info 736041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,athletics,0,0,0, 532037425,A Lam Shin,KOR,female,1986-09-23,1.68,56,handball,0,0,0, 435962603,Aaron Brown,CAN,male,1992-05-27,1.98,79,athletics,0,0,1, 521041435,Aaron Cook,MDA,male,1991-01-02,1.83,80,taekwondo,0,0,0, 33922579,Aaron Gate,NZL,male,1990-11-26,1.81,,cycling,0,0,0, 173071782,Aaron Royle,AUS,male,1990-01-26,1.80,67,triathlon,0,0,0, 266237702,Aaron Russell,USA,male,1993-06-04,,98,volleyball,0,0,1, 382571888,Aaron Younger,AUS,male,1991-09-25,1.93,100,football,0,0,0, 87689776,Aauri Lorena Bokesa,ESP,female,1988-12-14,1.80,62,athletics,0,0,0,
执行sed -f script.sed ./file.csv后,仅能将female/male替换为F/M,但排球、跆拳道项目的姓名大写规则完全没生效。然而直接执行sed -E 's/^([^,]*,)([^,]+)((,[^,]*){5},(volleyball|taekwondo),)/\1\U\2\L\3/' file.csv却能正常生效,这是哪里出问题了?
解答
问题出在正则表达式的模式匹配规则上:
- 你直接用命令行执行时加了
-E选项,启用了扩展正则表达式(ERE),此时正则里的()(分组)和{5}(重复次数)会被当作特殊语法处理,能正确匹配目标行。 - 但执行脚本时没加
-E,sed默认使用基础正则表达式(BRE),BRE里()和{}是普通字符,必须加反斜杠转义成\(、\)、\{5\}才会被识别为分组和重复量词。你的脚本里没转义,所以正则完全匹配不到对应的行,自然不会执行替换。
两种解决办法:
- 执行脚本时加上
-E选项:sed -E -f script.sed ./file.csv - 修改脚本适配BRE规则:把正则里的分组和量词转义:
s/^\([^,]*,\)\([^,]\+\)\(\([^,]*,\)\{5\},\(volleyball\|taekwondo\),\)/\1\U\2\L\3/
推荐第一种方法,保持脚本的正则写法和你测试时一致,更直观易懂。
内容的提问来源于stack exchange,提问作者dutch adler
相关产品推荐
相关产品推荐

