Sed 用命令替换模式

Sed 用命令替换模式

的提案这个问题

假设我想替换<number with commas>in <number>string something, "10,000", something

数字可以是1,00010,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此外,它的语言没有提供任何机制来调用另一个命令,就像其他一些编辑/处理语言所做的那样(例如,编辑器中的基本命令rw命令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

相关内容