【问题标题】:Replace text for every nth instance in a line替换一行中每第 n 个实例的文本
【发布时间】:2021-07-24 08:17:21
【问题描述】:

我希望在给定的行中用字符“+”替换每 6 个空格实例:

现在是所有好人来援助他们国家的时候了。一个木夹头能夹多少木头?

尝试: sed "s/ /+/6;P;D" text.txt

产量:

现在是 All+Good Men 来援助他们国家的时候了。一个木夹头能夹多少木头?

我想要:

现在是所有+好人前来援助他们国家的时候了。木头夹头可以夹多少+木头?

如果替换不起作用,我可以处理插入。

【问题讨论】:

    标签: bash loops sed


    【解决方案1】:

    使用 GNU sed:

    在+ 之后插入\n 并附加到您的命令| tr -d '\n'。

    【讨论】:

    • 这可能是最好的方法。我想不出任何改进。
    • 我刚刚用一个 GNU sed 发现了这一点:sed -E 's/([^ ]+ ){6}/&+/g; s/ \+/+/g' file
    • 现在更好了,想想单词后跟空白,然后修剪额外的空白。这值得第二个,但我只有 1 个。
    • 单次替换:sed -E 's/([^ ]*( [^ ]+){5}) /\1+/g'
    【解决方案2】:

    这是一种使用while 循环的方法:

    LINE="Now is the Time for All Good Men to Come to the Aid of their Country. How much wood could a wood chuck chuck?"
    
    MAX=$(echo $LINE | grep -o " " | wc -l) # this counts number of spaces in $LINE
    
    COUNTER=6
    while [ $COUNTER -lt $MAX ]; do 
      LINE=$(echo $LINE | sed "s/ /+/${COUNTER};P;D")
      COUNTER=$(echo $(($COUNTER + 5)) )
    done
    
    echo $LINE
    #Now is the Time for All+Good Men to Come to the+Aid of their Country. How much+wood could a wood chuck chuck?
    

    在while 循环中,我使用$COUNTER + 5(不是+ 6),因为我们必须考虑从上一次迭代中已经变为“+”的空间(因此它每6 替换一次空间-minus-1 个实例)。

    【讨论】:

      【解决方案3】:

      这可能对你有用(GNU sed):

      sed -E ':a;ta;s/ /+\n/6;H;tb;z;x;s/\n//gp;d;:b;x;s/(.*)\n.*/\1/;x;D' file
      

      此解决方案将每 6 个空格替换为 +\n,并将结果附加到保留空间。

      当第一次替换失败时,在首先删除任何引入的换行符后,将调用并打印保留空间。

      注意此解决方案严格遵守 OP 规范“在给定的行中用字符“+”替换空格的每 6 个实例”,但可以很容易地更改为遵循一组空格而不是一个空格,使用:

      sed -E ':a;ta;s/ +/+\n/6;H;tb;z;x;s/\n//gp;d;:b;x;s/(.*)\n.*/\1/;x;D' file
      

      另请注意习语:a;ta 重置替换内部成功开关,这是必要的,因为D 命令可能会使开关保持打开状态。

      【讨论】:

        猜你喜欢
        • 2018-09-13
        • 2017-12-01
        • 1970-01-01
        • 2016-02-13
        • 2021-07-26
        • 2015-08-07
        • 2021-10-18
        • 2013-08-18
        • 1970-01-01
        相关资源
        最近更新 更多