【问题标题】:replace several matches of a substring with their indexes用它们的索引替换子字符串的几个匹配项
【发布时间】:2020-05-30 11:34:59
【问题描述】:

假设你有一个字符串多次出现相同的子字符串,用另一个包含数学索引的子字符串替换匹配项的最佳单行代码是什么?例如,假设您有以下字符串:This is a test.,我们希望将所有出现的is 替换为X 及其索引,使其类似于:ThX-0 X-1 a test.

对此有什么想法吗?

【问题讨论】:

    标签: string bash awk sed


    【解决方案1】:

    Perl 来救援!

    echo 'This is a test.' | perl -pe 's/is/"X-" . $c++/ge' 
    
    • -p 逐行读取输入,运行代码并输出处理后的行。
    • s///g 在全局范围内进行替换,即在所有可能的位置上进行替换
    • /e 将替换部分解释为代码并运行它。这里的代码对字符串X-$c的值使用串联运算符.,同时加一。

    【讨论】:

    • 如果你想让它不区分大小写怎么办?
    • 只需添加/i修饰符,即/gei
    • 谢谢,它有效。它工作正常。但是,您如何将计数器的范围限制为行?我的意思是,如果您希望索引在每行中从 0 开始,该怎么办?
    • @amin:然后在替换前加上$c=0;
    【解决方案2】:

    awk 中的简单解决方案是:

    awk '{while(sub(/[iI][Ss]/,"X-"count++)){a=""};count=""} 1' Input_file
    

    或者根据 anubhava 先生的评论添加上述代码的较短版本:

    awk '{while(sub(/[iI][Ss]/,"X-"count++));count=""} 1'  Input_file
    

    简单的解释是,运行一个循环,直到找到一个替换并且在其中什么都不做:) 最后打印该行。

    【讨论】:

    • 这可能会更短:awk '{while(sub(/[iI][Ss]/,"X-"count++));} 1'
    • @anubhava,谢谢你先生现在添加了这个版本,干杯。
    • 谢谢你们。有用。但是,您如何将计数器的范围限制在行内?我的意思是,如果您希望索引在每一行中从 0 开始呢?
    • @amin,现在确定已经完成了更改,这些将从每行中从 0 开始的 X- 计数开始,如果有任何疑问,请让我知道。
    【解决方案3】:

    这是另一种 gnu-awk one liner:

    echo 'This is a test.' | awk -v RS='[iI][sS]' '{ORS = "X-" i++} 1'
    

    ThX-0 X-1 a test.
    

    重置每一行的计数器:

    printf '%s\n%s\n' 'This is a test.' 'This is another this' |
    awk -v RS='[iI][sS]' '/\n/{i=0} {ORS = "X-" i++} 1'
    

    ThX-0 X-1 a test.
    ThX-0 X-1 another thX-2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-16
      • 2015-08-17
      • 2014-03-12
      相关资源
      最近更新 更多