我有一个包含大量文本和一些描述数字的数字的文件< 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
的情况。当然,如果您能对此提供帮助,我将不胜感激。
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//
:删除上面后面的字符串中的前导零。
除了 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
这可能对你有用(GNU sed):
sed -r 's/0\.(([1-9][0-9])|0([0-9])).*/\2\3/' file
这使用交替和反向引用(BR)来匹配所需的模式。 如果第一个模式匹配,第二个 BR 将返回该值,第三个 (BR) 将为空。同样,如果交替中的第二个模式匹配,则第二个 BR 将为空,第三个 BR 将返回所需的值。