【问题标题】:使用 sed 自己替换每个字符,后跟 $n 次字符?
【发布时间】:2022-01-23 16:25:03
【问题描述】:

我正在尝试运行下面的命令来替换 DECEMBER 中的每个字符本身,后跟 $n 个问号。我尝试像 {$n} 那样转义 {$n} 并保持原样。然而我的输出一直是 D?{$n}E?{$n}... 用 sed 就不可能做到这一点吗?

我该怎么办呢。

echo 'DECEMBER' > a.txt
sed -i "s%\(.\)%\1\(?\){$n}%g" a.txt
cat a.txt

【问题讨论】:

  • 您说您想要一种使用$n 的方法,但接受了一个不使用(也不容易适应)使用$n 的答案。

标签: sed regexp-replace


【解决方案1】:

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

n=5
sed -E ':a;s/[^\n]/&\n/g;x;s/^/x/;/x{'"$n"'}/{z;x;y/\n/?/;b};x;ba' file

将换行符附加到行中的每个非换行符 $n 次,然后将所有换行符替换为预期的字符 ?

注意换行符被选为初始替换字符,因为它不可能在一行中(sed 使用换行符分隔行),并且如果当前行中已经存在最终替换字符,则替换是正确的。

【讨论】:

    【解决方案2】:

    范围(也称为区间或限制量词),例如 {3} / {3,} / {3,6},是 regex 的一部分,而不是 replacement 模式。

    你可以使用

    sed -i "s/./&$(for i in {1..7}; do echo -n '?'; done)/g" a.txt
    

    online demo

    #!/bin/bash
    sed "s/./&$(for i in {1..7}; do echo -n '?'; done)/g" <<< "DECEMBER"
    # => D???????E???????C???????E???????M???????B???????E???????R???????
    

    这里,. 匹配任何字符,替换模式中的&amp; 将其放回原处,$(for i in {1..7}; do echo -n '?'; done) 在其后添加七个问号。

    【讨论】:

      【解决方案3】:

      这个单线应该可以解决问题:

      sed 's/./&'$(printf '%*s' "$n" '' | tr ' ' '?')'/g' a.txt
      

      假设$n 扩展为正整数并且命令在POSIX shell 中执行。

      【讨论】:

        【解决方案4】:

        在设置n=2 后,在每个 Unix 机器上的任何 shell 中有效地使用任何 awk:

        $ awk -v n="$n" '
            BEGIN {
                new = sprintf("%*s",n,"")
                gsub(/./,"?",new)
            }
            {
                gsub(/./,"&"new)
                print
            }
        ' a.txt
        D??E??C??E??M??B??E??R??
        

        要“就地”进行更改,请将 GNU awk 与 -i inplace 一起使用,就像 GNU sed 与 -i 一样。

        警告 - 如果您要在替换文本中使用的字符是 &amp;,那么您需要在 BEGIN 部​​分使用 gsub(/./,"\\\\\\&amp;",new) 以使其被视为文字而不是反向引用元字符。使用任何 sed 解决方案和在脚本周围使用双引号的任何解决方案都会遇到这个问题以及更多问题(例如处理 \1/),在处理 $s 和具有外壳的解决方案时会遇到更多问题扩展未引用的脚本会在全局字符方面遇到更多问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-17
          • 2023-03-23
          • 1970-01-01
          • 2014-10-16
          • 2014-03-07
          • 2016-07-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多