【问题标题】:sed/awk: replace megabytes with bytes (insert zeros)sed/awk:用字节替换兆字节(插入零)
【发布时间】:2015-07-30 12:44:52
【问题描述】:

我有 .csv 文件,其中字段用逗号分隔,行由 \n 分隔。 在某些行中,我有兆字节符号。我想用零替换它以具有(或多或少)正确的字节大小。

我拥有的是

,2.6M,

我想拥有

,2600000,

示例

2015-06-01 00:04:52.736,10.0.0.2,10.0.0.4,443,443,56923,2.6 M,10.156.119.1
2015-06-01 00:04:56.736,10.0.0.2,10.0.0.4,443,58935,55658,1.3 M,10.156.126.1
2015-06-01 00:04:56.736,10.0.0.2,10.0.0.4,443,86,54801,1256,10.156.119.1
2015-06-01 00:04:52.736,10.0.0.2,10.0.0.4,443,49652,443,1.6 M,10.156.119.1
2015-06-01 00:04:53.732,10.0.0.2,10.0.0.4,443,443,55770,4.9 M,10.156.119.1
2015-06-01 00:04:54.732,10.0.0.2,10.0.0.4,443,80,45980,639,10.156.119.1
2015-06-01 00:04:54.732,10.0.0.2,10.0.0.4,443,63951,27058,1.2 M,10.156.119.1
2015-06-01 00:04:54.732,10.0.0.2,10.0.0.4,443,80,41035,13.8 M,10.156.119.1
2015-06-01 00:04:55.736,10.0.0.2,10.0.0.4,443,80,40078,7.9 M,10.156.119.1
2015-06-01 00:04:56.732,10.0.0.2,10.0.0.4,443,42008,4.5 M,10.156.119.1

目标

2015-06-01 00:04:52.736,10.0.0.2,10.0.0.4,443,443,56923,2600000,10.156.119.1
2015-06-01 00:04:56.736,10.0.0.2,10.0.0.4,443,58935,55658,1300000,10.156.126.1
2015-06-01 00:04:56.736,10.0.0.2,10.0.0.4,443,86,54801,1256,10.156.119.1
2015-06-01 00:04:52.736,10.0.0.2,10.0.0.4,443,49652,443,1600000,10.156.119.1
2015-06-01 00:04:53.732,10.0.0.2,10.0.0.4,443,443,55770,4900000,10.156.119.1
2015-06-01 00:04:54.732,10.0.0.2,10.0.0.4,443,80,45980,639,10.156.119.1
2015-06-01 00:04:54.732,10.0.0.2,10.0.0.4,443,63951,27058,1200000,10.156.119.1
2015-06-01 00:04:54.732,10.0.0.2,10.0.0.4,443,80,41035,13800000 M,10.156.119.1
2015-06-01 00:04:55.736,10.0.0.2,10.0.0.4,443,80,40078,7900000,10.156.119.1
2015-06-01 00:04:56.732,10.0.0.2,10.0.0.4,443,42008,4500000,10.156.119.1

【问题讨论】:

  • 正确的倍数不应该是1024*1024吗?

标签: regex bash csv awk sed


【解决方案1】:

由于示例数据中的最后一行缺少一列,这很复杂。

awk 'BEGIN {FS=OFS=","} {$(NF-1)=$(NF-1)*1000000} 1' file

如果有时你有“M”,有时有“K”,我们可以适应:

awk '
    BEGIN {
      FS=OFS=","
      mult[""]=1
      mult["K"]=1000
      mult["M"]=1000000
      mult["G"]=1000000000
    } 
    {
      split($(NF-1), a, " ")
      $(NF-1) = a[1] * mult[a[2]]
      print
    }
'

【讨论】:

  • 这里需要注意...数学乘法可能会给您带来不想要的结果,具体取决于您的数据库系统的引擎。例如对我来说,从 2.6 M 它给了 2.6 e^6 :)
【解决方案2】:
sed 's/\([0-9]*\)\.\([0-9]*\) M/\1\200000/' file

【讨论】:

  • 200000这个数字从何而来?
  • @t_thirupathi 是 \2 然后是 5 0s
  • @Marcaitus,这仅在小数点后只有一位数字时才有效。
  • @bro,它确实匹配并给出输出,但输出错误。它只是删除小数点并一直附加 5 0s。
  • @t_thirupathi,好的。确实如此。我没明白你的意思。 ;)
【解决方案3】:
sed 's/ \([KMG]\)/000000000\1/
     s/\.\([0-9]\{3\}[0-9]*K/\1/
     s/\.\([0-9]\{6\}[0-9]*M/\1/
     s/\.\([0-9]\{9\}[0-9]*G/\1/
    ' YourFile
  • 根据您的示例,我们应该更改 1000 单位的倍数的只有 1 个字母的数字

如果只有 M 出现在您的示例中,则可以使用 sed 's/\.\([^,]*\) M/\1000000/' YourFile 进行简化(仅在使用 M 表示值的点后有 1 个数字)

【讨论】:

    最近更新 更多