【问题标题】:Changing output text with sed使用 sed 更改输出文本
【发布时间】:2014-05-03 06:40:21
【问题描述】:

我在使用 sed 在 BASH 中格式化文本时遇到问题。 这是输入文件:

recfun.o -> timeout.o (set_timeout)
recursive.o -> timeout.o (timeout)
print_recursive.o -> recursive.o (ackermann)
rec-nam.o -> timeout+.o (timeout)

这应该是输出:

recfunDo -> timeoutDo [label="set_timeout"];
recursiveDo -> timeoutDo [label="timeout"];
print_recursiveDo -> recursiveDo [label="ackermann"];
rec_namDo -> timeoutPDo [label="timeout"];

这意味着:

替换: “-”代表“_”,然后是“.”代表“D”,然后“+”代表“P”,但不要用“->”代替“_>”

我是这样使用 sed 的:

sed -e 's/./D/' file | sed -e 's/+/P/' | sed -e 's/-/_/'

但它返回相同的输出,只是 D 替换了每行中的第一个字母。

感谢您的帮助!

【问题讨论】:

    标签: bash text sed


    【解决方案1】:

    . 匹配模式中的任何字符,因此它总是改变第一个字母。将其转义为 \. 会有所帮助。完整的命令:

    sed 's/\./D/g; s/+/P/g; s/-\([^>]\)/_\1/; s/(/[label="/; s/)/"];/' myfile 
    recfunDo -> timeoutDo [label="set_timeout"];
    recursiveDo -> timeoutDo [label="timeout"];
    print_recursiveDo -> recursiveDo [label="ackermann"];
    rec_namDo -> timeoutPDo [label="timeout"];
    

    正如 Trenin 在评论中指出的那样,以; 分隔的多个命令在此处分组在一个 sed 脚本中。 s/-\([^>]\)/_\1/ 部分使用以\(...\) 表示的编号组(在替换部分中将其称为\1)和组内的字符类:[^>]。这匹配除> 之外的任何字符。

    【讨论】:

    • 您可能需要添加一些解释。例如,OP 可能不知道您可以使用; 链接多个命令。此外,为了绕过替换->,您匹配了-,后跟> 以外的任何内容。不过答案很好!
    【解决方案2】:

    你需要转义.

    sed -e 's/\./D/g' file
    

    【讨论】:

    • 也可以使用/g 在同一行中进行多次替换。
    • @fedorqui 错过了global,已修复
    • 哦,我明白了,抱歉,我是 bash 新手
    • @user3021851 从技术上讲,这不是 bash 功能,它只是 sed 正则表达式(参见例如here)。
    【解决方案3】:

    Perl 的正则表达式在这里很方便:

    perl -pe 'tr/.+/DP/; s/-(?!>)/_/g; s/\((.+?)\)$/[label="$1"];/'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      • 1970-01-01
      • 2018-10-07
      • 2014-04-09
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      相关资源
      最近更新 更多