【问题标题】:Find and replace regular expression with alternate format使用替代格式查找和替换正则表达式
【发布时间】:2020-04-29 06:16:32
【问题描述】:

我有一个文件,其中的行包含这样的文本

something,12:3456789,somethingelse
foobar,12:345678,somethingdifferent

对于行中第二项在: 之后有6 位数字的行,我想通过在前面添加一个0 并移动: 来改变它的格式。例如上面会变成:

something,12:3456789,somethingelse
foobar,01:2345678,somethingdifferent

我不知道如何使用 sed 或任何 unix 命令行工具来做到这一点

【问题讨论】:

    标签: regex sed grep find


    【解决方案1】:

    你只需要匹配你有 2 位数字的中间部分,然后是 :,然后是 恰好 6 位数字。如果您适当地在各个组中捕获文本,您可以在结果中移动它们。请注意,模式末尾的 \b 字边界是为了确保我们完全匹配 6 位数字,而不匹配具有完整 7 位数字的行:

    /\b(\d)(\d):(\d{6})\b/0\1:\2\3/
     |__________________| |______|
           pattern       replacement
    

    这给出了预期的输出。可以在线试用here


    sed 没有 Perl 样式说明符,例如 \d。相反,您需要使用[[:digit:]]。这是适用于sed的更新正则表达式

    sed -E 's/\b([[:digit:]])([[:digit:]]):([[:digit:]]{6})\b/0\1:\2\3/g' myfile.txt
    

    正如@Jonathan Leffler 指出的那样,\b 不适用于 Mac 的 sed,因此您需要在正则表达式模式的前后添加逗号,然后在替换模式中将它们替换回

    【讨论】:

    • 我正在运行这个命令,但它不会在 mac sed 上执行任何操作。 sed -i -E 's/,\(\d\)\(\d\):\(\d{6}\),/\|0\1:\2\3\|/' myfile.txt
    • @Anthony:Mac 中的-i 选项sed 需要一个非空参数,因此它使用-E 作为备份后缀——这反过来意味着您没有使用扩展常用表达。如果您想就地编辑(在知道代码可以工作之前很危险),那么-i ''(一个空字符串作为备份后缀)是必要的。如果脚本必须在 Mac 和 Linux 之间传输,那么您需要在 -i 选项上附加一个非空后缀:-i.bak
    • Mac sed 无法识别 \b,因此鉴于该字段被逗号包围,您需要使用 sed -E 's/,([[:digit:]])([[:digit:]]):([[:digit:]]{6}),/,0\1:\2\3,/g' — 这会更改 Mac 上的数据,并且应该可以工作在 Linux 等上也是如此。
    • OP 说“对于行中第二项在 :... 之后有 6 位数字的行”,如果第二项不符合上述标准,则此解决方案可能会给出误报,但另一个做。正则表达式应将匹配锚定到第二项,即/^[^,]*,second_item,/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 2011-06-16
    相关资源
    最近更新 更多