如何从sed的时间戳中删除毫秒?

时间:2011-12-18 17:47:29

标签: regex sed grep

我的输入文件如下:

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

5 个答案:

答案 0 :(得分:5)

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

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

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

我选择只工作一次;你正在做三个。最终,给定系统形成的输入数据,结果没有差异 - 但脚本的可读性存在(小)差异。

答案 1 :(得分:2)

尝试:

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

另外,请尝试\d而不是[0-9],您的sed版本可能会支持此版本。

答案 2 :(得分:1)

你在附近但是某些角色在sed中很特别(至少在我的版本中):{}(),但不是{{ 1}}。所以你需要用反斜杠来逃避它们。

并且:在paretheses之间表达,它应该是第一部分直到秒,而不是第二部分。

您的版本的修改可能是:

\1

答案 3 :(得分:0)

这可能对您有用:

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

答案 4 :(得分:0)

由于已发布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解析第二个和第三个字段时,使用substitution我们会对字段执行for loop
  4. 如果字段不是第2和第3,那么我们只打印字段。
  5. 最后,由于我们使用了for loop <NF,我们只打印出$NF这是最后一个字段。这不会导致在最后一个字段后打印,