我有多次出现的模式:
)0.[0-9][0-9][0-9]:
其中[0-9]是任何数字,在各种文本上下文中但该模式作为此正则表达式是唯一的。我需要将小数部分转换为整数(百分比值从0到99)。
一个小例子字符串是
=1:0.00055)0.944:0.02762)0.760:0
转入
=1:0.00055)94:0.02762)76:0
我正在做的是:
cat file | sed -e "s/)\([0-9].[0-9][0-9][0-9]\):/)`echo "\1"|awk '{ r=int(100*$0); if((r>=0)&&(r<=100)){ print r; } else { print "error"; exit(-1); } }'`:/g"
但输出为)0:
故障在哪里?...
答案 0 :(得分:2)
既然你问'错误在哪里'而不是'如何解决问题':
您的反引用管道echo ...|awk ...
首先执行,生成一个0
,然后将其作为传递给s///
的{{1}}命令的一部分,从而替换模式匹配的所有位置。 PS:使用更新的(后里根)和更灵活的命令替换符号sed
而不是反引号在除csh系列之外的所有shell中都是首选,尤其是在Stack上,其中反引号特别用于降价并且在文本中显示麻烦
如果你想真正解决你没有清楚或完全描述的问题,可以指出更好的方向:
标准sed无法执行命令来生成替换文本; GNU sed可以使用标记$( ... )
,但是您需要将整个模式空间作为命令,并将其他任何内容放入holdspace中,这很乏味。 perl可以在s的替换中计算表达式,包括算术; awk(甚至是gawk)不能直接这样做,但你可以通过匹配和替换/重建作为单独的步骤来获得相同的效果,具体取决于你想要做什么的未明确和不清楚的细节;如果你想保持线的其余部分不变,比如:
e
但是如果你对截断感到满意的话,你实际上并不需要算术。只需丢弃前导数字0.和最后一位数字并保持两位数字:
awk 'match($0,/)0[.][0-9][0-9][0-9]:/){ print substr($0,1,RSTART) (substr($0,RSTART+1,RLENGTH-2)*100) substr($0,RSTART+RLENGTH-1) }'
注意{regexp中的 sed 's/)0[.]\([0-9][0-9]\)[0-9]:/)0.\1:/g'
除非转义或在charclass(正如我所做的)匹配任何字符而不仅仅是句点,这可能是也可能不是问题,因为你没有给出其余的输入。
PS:过程退出状态的负数不起作用(IIRC计划9除外)。使用小的(通常<128)正状态值来表示错误;最常见的是只使用1。
答案 1 :(得分:1)
检查此perl 单行命令:
perl -pe 's/\)(\d+\.\d+):/sprintf ")%d:", $1 * 100/ge' file
之前:
=1:0.00055)0.944:0.02762)0.760:0
之后:
=1:0.00055)94:0.02762)76:0
如果您需要替换真实编辑模式,请添加-i
开关:
perl -i -pe '...'