【问题标题】:Using sed to replace the first instance of an entire line beginning with string使用 sed 替换以字符串开头的整行的第一个实例
【发布时间】:2013-03-09 20:08:57
【问题描述】:

我正在尝试编写一个 bash 脚本,该脚本将使用 sed 替换以给定字符串开头的文本文件中的整行,并且我只希望它在第一个匹配项时执行此替换。

例如,在我的文本文件中,我可能有:

hair=brown
age=25
eyes=blue
age=35
weight=177

我可能想简单地将第一次出现的以“age”开头的行替换为不同的数字,而不会影响第二个 age 实例:

hair=brown
age=55
eyes=blue
age=35
weight=177

到目前为止,我想出了

sed -i "0,/^PATTERN/s/^PATTERN/PATTERN=XY/" test.txt

但这只会替换字符串“age”本身而不是整行。我一直试图在某处扔一个“\ c”来改变整条线,但到目前为止没有任何效果。有没有人对如何解决这个问题有任何想法?谢谢。

【问题讨论】:

  • 我相信有人会发布更好的方法,但对脚本的最小更改是编写sed -i "0,/^PATTERN/ s/^PATTERN=.*$/PATTERN=XY/" test.txt(因为.*$ 与该行的其余部分匹配)。
  • 是否可以使用您的示例将以AGE 开头的行替换为AGE=55 来重写解决方案?

标签: bash sed


【解决方案1】:

就像@ruakh 建议的那样,您可以使用

sed -i "0,/^PATTERN/ s/^PATTERN=.*$/PATTERN=XY/" test.txt

一种更短且重复性更低的方法是

sed -i '0,/^\(PATTERN=\).*/s//\1XY/' test.txt

它利用了反向引用以及在 s 表达式中不指定模式将使用先前匹配的模式这一事实。

【讨论】:

    【解决方案2】:

    0,...-ranges 仅适用于GNU sed。另一种方法可能是使用带有sed 的shell 重定向:

    { sed '/^\(PATTERN\).*/!n; s//\1VAL;q'; cat ;} < file
    

    或使用awk:

    awk '$1=="LABEL" && !n++ {$2="VALUE"}1' FS=\\= OFS=\\= file
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-25
      • 1970-01-01
      • 2014-03-07
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多