的提案这个问题。
假设我想替换<number with commas>
in <number>
string something, "10,000", something
。
数字可以是1,000
,10,000
...等等。
我正在尝试是否可以使用命令进行替换:
echo 'something, "10,000", something' | sed "s/\(\".*\"\)/$(echo \\1 | sed 's/,//')/"
这不起作用,什么也不会发生。
引发我问题的是,如果我只使用echo
echo 'something, "10,000", something' | sed "s/\(\".*\"\)/$(echo \\1)/"
参数\\1
读取正常,但看起来无法通过管道传输到sed
(或grep
)。
这在某种程度上可能吗?
答案1
作为表达式一部分的命令替换的扩展sed
发生在sed
命令执行之前。
这意味着shell要执行命令
sed "s/\(\".*\"\)/$(echo \\1 | sed 's/,//')/"
第一次运行
echo \\1 | sed 's/,//'
此输出是\1
因为 输出的字符串中没有逗号echo
。
然后 shell 将此字符串插入到命令替换的位置,产生
sed "s/\(\".*\"\)/\1/"
如果我们在 shell 中启用跟踪来运行管道,这一点也很清楚:
$ set -x
$ echo 'something, "10,000", something' | sed "s/\(\".*\"\)/$(echo \\1 | sed 's/,//')/"
+ echo 'something, "10,000", something'
+ echo '\1'
+ sed s/,//
+ sed 's/\(".*"\)/\1/'
something, "10,000", something
在第二个管道中,会发生同样的事情(减去 的执行sed 's/,//'
):
$ set -x
$ echo 'something, "10,000", something' | sed "s/\(\".*\"\)/$(echo \\1)/"
+ echo 'something, "10,000", something'
+ echo '\1'
+ sed 's/\(".*"\)/\1/'
something, "10,000", something
结论是:是不是可以sed
使用命令替换来处理与正则表达式匹配的子字符串,从内部调用另一个 shell 命令,因为命令替换是在调用之前处理sed
的(以便sed
在调用之前解析编辑脚本是什么sed
)。
sed
此外,它的语言没有提供任何机制来调用另一个命令,就像其他一些编辑/处理语言所做的那样(例如,编辑器中的基本命令r
和w
命令ed
允许这样做awk
)。
答案2
sed 's/\([0-9]\),\([0-9]\)/\1\2/g'
仅当两个逗号之间至少有两个数字时,此方法才有效,因此
123,456,789 -> 123456789
12,34,56,78 -> 12345678
but
1,2,3,4,5,6 -> 12,34,56