我有一个这样的数据:
cat file
(4567.99,5678.98)
(5678.33,6734.34)
我想要的输出是:
(45679900 56789800)
(56783300 67343400)
我想取消小数,让它变成8位数字,并删除逗号符号,让它之间有空格。
使用awk
命令,怎么做?sed
也可以。
答案1
使用 awk:
awk -F'[(),]' '{ printf( "(%d %d)\n", $2 * 10000, $3 * 10000 ); }' file
答案2
sed -e 's/,/ /' -e 's/\.\(..\)/\100/g'
答案3
TXRawk 宏:我们实际上可以将其作为类型化操作来执行:将数据获取为浮点值,将它们向下取整到最接近的整数,乘以一百,转换为整数。
然而,让我们暂停一下并思考一下,如果值太大以至于无法截断为最接近的整数,那么这可能是一个坏主意;对于任意大的值,按文本执行此操作都是正确的。
$ txr -e '(awk (:begin (set ft #/\d+.\d+/))
((mf tofloat floor toint (* 100))))'
(4567.99, 123.45, junk 3.1415, 1.0 ...) x
456700 12300 300 100
变量ft
是一个新特性;经典的 Awk 没有同等的东西。而fs
类似于FS
(字段分隔符),ft
意味着“字段标记化”:它指定一个正则表达式,用于识别和提取字段,忽略之间不匹配的内容。
讽刺的是,
ft
可以直接表达 Awk 中默认字段分隔符的语义:从记录中修剪前导和尾随换行符和空格,并以一个或多个换行符或空格分隔。这正好相当于简单地积极地将字段识别为由非空格组成的标记!如果 Awk 有一个FT
变量,它就不需要当FS
等于单个空格时应用的特殊技巧;默认值可能FS
未设置,而是FK
设置为 regex[ \t\n]+
。
我们使用一个简单的方法ft
来识别数字、强制小数和强制数字。没有前导标志,没有可选部件。
宏mf
(“映射字段”)将每个字段放入操作管道中。首先,该tofloat
函数将字符串转换为浮点型。然后floor
向负无穷大截断为最接近的整数。toint
让我们回到 inger 并表示to(* 100)
的部分应用:一个接受附加参数并乘以它们的乘积的函数。这种部分应用语法遵循以下事实:参数被隐式地视为语法:TXR Lisp 显式部分应用运算符。*
100
100
mf
op
由于mf
返回非nil
结果,因此默认操作(prn)
会启动打印更新的rec
,它是通过将更新的字段与ofs
由一个空格字符组成的默认字段连接起来重新构成的,并输出ors
默认为换行符的 。
这是一种以数字方式进行计算的方法,但不依赖浮点数学。基本上我们可以使用相同的正则表达式提取字段,但然后在它们仍然是文本时删除点。然后转到整数并使用截断整数除法和乘法:
$ txr -e '(awk (:begin (set ft #/\d+.\d+/))
((mf (remq #\.) toint (trunc @1 100) (* 100))))'
由于在这种语言中整数可以是任意大,因此该解决方案不会因数字很大而出现问题,但可以最大限度地减少文本处理。
答案4
awk '{gsub(/\./,"")sub(/,/," "); print $1"00",$2}' file
(45679900 567898)
(56783300 673434)