【问题标题】:How to remove the milliseconds from timestamps with sed?如何使用 sed 从时间戳中删除毫秒?
【发布时间】:2011-12-19 07:22:21
【问题描述】:

我的输入文件如下:

12/13/2011,07:14:13.724,12/13/2011 07:14:13.724,231.56.3.245,LasVegas,US

我希望得到以下内容:

12/13/2011,07:14:13,12/13/2011 07:14:13,231.56.3.245,LasVegas,US

我试过了,但没有成功:

sed "s/[0-9]{2}\:[0-9]{2}\:[0-9]{2}\(\.[0-9]{1,3}\)/\1/g" input_file.csv > output.csv

【问题讨论】:

    标签: regex sed grep


    【解决方案1】:
    sed 's/\(:[0-9][0-9]\)\.[0-9]\{3\}/\1/g' input_file.csv > output.csv
    

    你快到了。在经典的sed 中,您必须在括号和大括号前使用反斜杠才能将它们变成元字符。 sed 的某些版本可能具有反转操作的机制,因此大括号和圆括号默认为元字符,但这在跨平台时并不可靠。

    另外(强烈推荐):在 sed 命令周围使用单引号。否则,shell 会在 sed 看到之前解释那些反斜杠(以及任何 $ 符号等)。通常,这会使编码器(尤其是维护编码器)感到困惑。事实上,尽可能在程序的参数周围使用单引号。不要对此感到偏执 - 如果您需要插入变量,请这样做。但是单引号通常更容易编码,最终也更容易理解。

    我选择只处理一个时间单元;你正在研究三个。最终,给定系统形成的输入数据,结果没有差异 - 但脚本的可读性存在(小)差异。

    【讨论】:

    • 谢谢乔纳森。这工作正常,但现在想知道为什么我的正则表达式没有做到这一点......
    • 准确回答,深入解释我的错误,大大!谢谢!
    【解决方案2】:

    试试:

    sed 's,\(:[0-9]\{2\}\).[0-9]\{3\},\1,g'
    

    另外,试试\d 而不是[0-9],你的sed 版本可能支持。

    【讨论】:

    • 我相信你必须避开大括号(即\{\}),否则看起来不错。
    • 因为你捕获了你想要删除的内容 :p (\(\.[0-9]{1,3}\))
    • 是的,我误解了正则表达式的“正则表达式捕获”部分;)谢谢!
    【解决方案3】:

    您在附近,但某些字符在 sed 中是特殊的(至少在我的版本中):{}(),但不是 :。所以你需要用反斜杠转义它们。

    \1 在括号之间表达,它应该是第一部分直到几秒钟,而不是第二部分。

    您的版本的修改可能是:

    sed "s/\([0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\)\.[0-9]\{1,3\}/\1/g" input_file.csv > output.csv
    

    【讨论】:

      【解决方案4】:

      这可能对你有用:

       sed 's/\....//;s/\....//' input_file.csv >output_file.csv
      

      【讨论】:

        【解决方案5】:

        由于sed 解决方案已经发布,这里有一个替代awk 解决方案:

        [jaypal:~/Temp] cat inputfile
        12/13/2011,07:14:13.724,12/13/2011 07:14:13.724,231.56.3.245,LasVegas,US
        
        [jaypal:~/Temp] awk -F"," -v ORS="," '
        {for(i=1;i<NF;i+=1) 
        if (i==2||i==3) {sub(/\..*/,"",$i);print $i} 
        else print $i;printf $NF"\n"}' inputfile
        12/13/2011,07:14:13,12/13/2011 07:14:13,231.56.3.245,LasVegas,US
        

        说明:

        1. 将字段分隔符设置为,,将输出记录分隔符设置为,
        2. 使用for loop,我们将遍历每个字段。
        3. 使用if loop,当for loop 解析第二个和第三个字段时,我们将对字段执行substitution
        4. 如果字段不是第 2 和第 3,那么我们只需打印出字段。
        5. 最后,因为我们使用for loop 代替&lt;NF,所以我们只打印出$NF,这是最后一个字段。这不会导致在最后一个字段之后打印 ,

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-04-06
          • 2012-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多