如何使用num2words.sh替换文本数字,解决sed捕获组传参异常问题
问题分析
你原来的写法不生效有两个核心原因:
- 语法错误:替换规则里多写了一个多余的右括号
) - 逻辑错误:Shell 的命令替换
$(...)优先级高于 sed 执行逻辑,在 sed 启动前$(./num2words.sh \1)就已经执行了,此时\1只是普通字面量,不会被替换为sed匹配到的数字捕获组,自然无法传入脚本得到正确结果。
可行解决方案
方案1:GNU Sed 实现(优先推荐)
GNU Sed 支持s命令的e修饰符,可以将替换完成后的字符串作为Shell命令执行,再将命令的输出结果作为最终替换内容,写法如下:
sed -E 's/([0-9]+)/.\/num2words.sh \1/ge' file1.txt
参数说明:
-E开启扩展正则,不需要转义括号和+g全局替换,一行内匹配多个数字也会全部替换e执行替换后的字符串作为Shell命令,返回执行结果作为替换值
注意:使用前请确保
num2words.sh有可执行权限(执行chmod +x num2words.sh添加权限),如果脚本不在当前工作目录请写绝对路径。如果需要直接修改原文件,可以加-i参数。
方案2:Awk 实现(兼容所有Unix-like系统)
如果使用的是 macOS 等没有GNU Sed的环境,可以用Awk实现,适配性更强:
awk '{ # 遍历当前行的所有字段 for(i=1; i<=NF; i++) { # 匹配纯数字字段 if($i ~ /^[0-9]+$/) { # 调用转换脚本获取结果 cmd = "./num2words.sh " $i cmd | getline res close(cmd) # 替换原数字字段 $i = res } } # 输出处理后的整行 }1' file1.txt
如果需要替换和其他字符连在一起的数字(比如
abc123def里的123),调整匹配逻辑拆分字段处理即可。如果需要修改原文件,将输出重定向到新文件后覆盖原文件即可:awk '...' file1.txt > tmp && mv tmp file1.txt
方案3:Perl 实现
Perl的正则替换支持内嵌代码执行,写法更简洁:
perl -pe 's/(\d+)/chomp(my $res = `./num2words.sh $1`); $res/ge' file1.txt
这里加chomp是为了去掉脚本输出末尾默认带的换行符,避免替换后出现多余换行。
注意事项
请确保num2words.sh输入单个数字时,仅输出对应的英文拼写,没有多余的日志、空行等内容,否则替换结果会出现异常。
内容的提问来源于stack exchange,提问作者qk2905
相关产品推荐
相关产品推荐

