【问题标题】:How to replace the nth occurrence of a sttring in a file using sed [duplicate]如何使用 sed 替换文件中第 n 次出现的字符串 [重复]
【发布时间】:2021-09-20 19:38:22
【问题描述】:

有什么方法可以用 sed 替换文件中第 n 次出现的字符串?

如何更改它以替换第 n 次出现?

我的文件内容如下:

first line 
second line 
third line
 jack
fifth line 
jack
 seventh line

考虑一个变量var = jill

我想用变量$var 的值替换第二次出现的jack。

【问题讨论】:

    标签: sed


    【解决方案1】:

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

    sed ':a;$!{N;ba};s/jack/'"$var"'/2' file
    

    这会将文件吞入内存,然后将第二次出现的jack 替换为$var

    编辑:

    1. :ab 命令的占位符,它告诉 sed 中断/跳转到位置,即 ba 跳转到 :a
    2. $! 是一个地址。 $ 表示文件结束,! 表示不是。放在一起这意味着任何不是文件结尾的地址。
    3. {...} 将大括号之间的命令分组。
    4. N 追加一个换行符,然后将下一行追加到模式空间,除非当它通过 sed 到刚刚传递最后一个命令时没有更多行(如果 -n 未设置,它将打印模式中的任何内容空格,如果设置了-n,它将结束处理)。
    5. s/jack/'$var"'/2 这是一个 sed 替换命令,将第二次出现的 jack 替换为 $var 的内容。注: '...' 有效地将 sed 命令分解到底层 shell,然后再次返回,允许插入 shell 变量。

    总之,整个文件被吞入内存,第二次出现的jack$var 的内容替换。

    在大多数情况下,这可以替换为:

    sed -z 's/jack/'"$var"'/2' file 
    

    【讨论】:

    • 非常感谢它的工作:)
    • 你能解释一下这东西在做什么吗:a;$!{N;ba};
    • @subhashnerella 不知道 $var 持有什么我只能猜测所有斜杠都需要通过添加反斜杠来转义。在您的评论中</Attribute> 不是。如果斜线在模式和替换中很常见,最好使用替代分隔符,例如#
    • @subhashnerella :a;$!{N;ba}; 将完整的文件读入模式空间。
    • 如你所知,你应该完整地解释你的解决方案,而不是评论和简短。
    【解决方案2】:

    如果您喜欢使用awk,这里是awk 版本

    awk -v c="$var" '/jack/ && ++a==2 {sub(/jack/,c)}1' file
    first line
    second line
    third line
     jack
    fifth line
    jill
     seventh line
    

    【讨论】:

    • 如果我想在 jack 的第二次出现中插入取自变量的 jill 以使其看起来像 jajillck,该命令将如何?
    • @subhashnerella 这会将输入一分为二并在其间添加一个字符串 inn:echo "jack" | awk '{s=length($1)/2;print substr($1,0,s)"jill"substr($1,s+1)}'
    猜你喜欢
    • 1970-01-01
    • 2020-08-16
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2018-08-11
    • 2021-12-05
    • 2018-04-11
    相关资源
    最近更新 更多