sed中的awk语句

时间:2018-02-21 22:38:08

标签: awk sed

我有多次出现的模式:

)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:

故障在哪里?...

2 个答案:

答案 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 -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 '...'