使用 sed 替换模式

问题描述 投票:0回答:3

我有一个包含大量文本和一些描述数字的数字的文件< 1 with three digits of precision. I'd like to replace those numbers with roughly equivalent integer percentages (numbers 0-99).

0.734 -> 73
0.063 -> 6
0.979 -> 97

正确舍入会很好,但不是必需的。

我尝试了以下几种变体,但似乎连一场比赛都没有:

sed -e 's/0\.(\d\d)/&/' myfile.txt

我理解的意思是,匹配数字 0,然后是小数点,捕获接下来的两位数字,并让 sed 用捕获的部分替换整个匹配。

即使我能做到这一点,我也不知道如何处理

0.063 -> 6
的情况。当然,如果您能对此提供帮助,我将不胜感激。

regex sed
3个回答
2
投票

sed
确实支持字符类,但使用更长的 POSIX 名称。数字是
[[:digit:]]
。直接写
[0-9]
就更短了。

试试这个:

sed -E 's/0\.([0-9][0-9]).*/\1/;s/^0//' myfile.txt

-E
标志告诉它使用现代正则表达式。这里实际上有 2 个命令,用
;
:

分隔

s/0\.([0-9][0-9]).*/\1/
:将
0
后面的两位数字和一个点放入捕获组中,并用该捕获组替换整个字符串。

s/^0//
:删除上面后面的字符串中的前导零。


0
投票

除了 Zoff 给出的

sed
答案之外,您还可以使用 awk 来更好地实现(带舍入):

#round down
awk '{print int($1*100)}' myfile.txt
#0.979 -> 97

#round up
awk '{printf "%.0f\n",$1*100}' myfile.txt
#0.979 -> 98

仅 bash 实现:

#round down
while read n; do result=$(bc <<< "$n*100"); echo ${result%%.*}; done < myfile.txt
#round up
while read n; do result=$(bc <<< "$n*100"); printf "%.f\n" $result; done < myfile.txt

0
投票

这可能对你有用(GNU sed):

sed -r 's/0\.(([1-9][0-9])|0([0-9])).*/\2\3/' file

这使用交替和反向引用(BR)来匹配所需的模式。 如果第一个模式匹配,第二个 BR 将返回该值,第三个 (BR) 将为空。同样,如果交替中的第二个模式匹配,则第二个 BR 将为空,第三个 BR 将返回所需的值。

© www.soinside.com 2019 - 2024. All rights reserved.