替换命令除非条件

时间:2014-09-12 15:24:04

标签: regex bash sed

我正在做一些数据清理,我需要运行一个基本上执行的bash脚本:

  • ":"
  • 替换每一个:

我使用sed -i -e 's/:/":"/g'文件名

执行此操作

问题是必须对一行中的每一次出现都要这样做,除非它是时间数据。

例如,如果我的行是

VolumeId:vol-c29a6e96, Size:8, timestamp:Thu Jan 09 13:44:02 UTC

我希望这是

VolumeId":"vol-c29a6e96, Size":"8, timestamp":"Thu Jan 09 13:44:02 UTC

所以每次数据格式为digit:digit时,我都不希望应用sed命令 我怎样才能做到这一点? (不需要sed命令)

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

另一个perl命令,

$ perl -pe 's/\d{2}:\d{2}:\d{2}(*SKIP)(*F)|:/":"/g' file
VolumeId":"vol-c29a6e96, Size":"8, timestamp":"Thu Jan 09 13:44:02 UTC

\d{2}:\d{2}:\d{2}(*SKIP)(*F)|:将完全跳过所有时间戳字符串,并匹配剩余字符串中的:。只需将匹配的:替换为":",即可获得所需的输出。

答案 1 :(得分:0)

由于您打开非sed选项,因此使用perl是一个选项(由于前瞻性支持):

s='VolumeId:vol-c29a6e96, Size:8, timestamp:Thu Jan 09 13:44:02 UTC'
perl -pe 's/(?<=\D):|:(?=\D)/":"/g' <<< "$s"
VolumeId":"vol-c29a6e96, Size":"8, timestamp":"Thu Jan 09 13:44:02 UTC

答案 2 :(得分:0)

一个sed答案:将时间戳中的冒号更改为其他角色,替换所有冒号,然后在时间戳中恢复冒号

echo "VolumeId:vol-c29a6e96, Size:18, timestamp:Thu Jan 09 13:44:02 UTC" | 
sed -r '
    s/([[:digit:]]{2}):([[:digit:]]{2}):([[:digit:]]{2})/\1T\2T\3/g
    s/:/":"/g
    s/([[:digit:]]{2})T([[:digit:]]{2})T([[:digit:]]{2})/\1:\2:\3/g
'
VolumeId":"vol-c29a6e96, Size":"18, timestamp":"Thu Jan 09 13:44:02 UTC