【问题标题】:macOS sed - Complex substitution commandmacOS sed - 复杂的替换命令
【发布时间】:2021-07-06 11:27:05
【问题描述】:

我有一个包含很多行的文本文件,需要使用 macOS sed 进行一些复杂的替换。解释我的问题有点困难,所以我先给你看一个例子:

文件:

#00101:A9AA%AAB
#03901:%E+2100009+X3800
#06008:01020304

预期输出:

#00101:0000%A00
#03901:%E+2000000+X0000
#06008:01020304

对于以“#xxx01:”开头的所有行(其中 x 代表任何数字),我需要将所有字母数字字符(AZ、0-9)替换为“0”,“:”之前的数字除外,并且任何以“%”或“+”开头的两字符序列。

我知道基本的替换和异常命令,以及使用“^”在行首搜索模式,但我对如何组合所有这些命令感到困惑。我该怎么做呢?如果这在 sed 中是不可能的,欢迎使用非 sed 解决方案。

【问题讨论】:

    标签: bash macos sed text-parsing


    【解决方案1】:

    创建一个文件script.sed,其中包含:

    /^#[0-9]{3}01:/ {
        :r
        s/:((0|[+%]..)*)[A-Za-z1-9]/:\10/
        t r
    }
    

    调用包含您的示例输入数据的文件data。 运行显示的命令以获得所需的输出:

    $ sed -E -f script.sed data
    #00101:0000%AA0
    #03901:%E+0000000+X3000
    #06008:01020304
    $
    

    -E 选项告诉sed 使用扩展的正则表达式。选项-f 告诉它从文件script.sed 中读取程序。

    模式/^#[0-9]{3}01:/ 查找以# 开头、后跟3 位数字、01 和冒号的行。 {} 之间的行将针对每个匹配行执行。

    :r 行创建了一个标签r,可以使用bt 命令分支到该标签。如果自上一个t 命令以来有一个成功的s/// 命令,则t r 分支到标签r

    s/:((0|[+%]..)*)[A-Za-z1-9]/:\10/ 命令搜索冒号,后跟任何0s 或+..%.. 字符序列(其中的点与任何字符匹配),然后是0 以外的字母数字字符.它用冒号、记住的匹配项和0 替换其他字母数字字符。如果你不省略0,你最终会陷入无限循环。

    您还可以使用命令行脚本代替脚本文件,可能带有多个-e 选项(脚本文件的每一行一个)或单个脚本选项和足够的分号。

    【讨论】:

    • 谢谢你,设法让它工作。我稍微修改了脚本,只在任何 % 或 +(%A、+9 等)之后查找一个字符,并且效果很好。
    • 我误读了要求——抱歉——但修复(删除两个点之一)不是火箭科学。
    猜你喜欢
    • 2014-12-28
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    相关资源
    最近更新 更多