sed:替换部分行

时间:2009-07-02 13:49:11

标签: sed

如何使用sed替换行的一部分?

该行

DBSERVERNAME     xxx

应替换为:

DBSERVERNAME     yyy

值xxx可以变化,dbservername和值之间有两个选项卡。此名称 - 值对是配置文件中的众多名称之一。

我尝试了以下反向引用:

echo "DBSERVERNAME    xxx" | sed -rne 's/\(dbservername\)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'

导致错误:`s'命令的RHS上的引用\ 1无效。

表达方式有什么问题?使用GNU sed。

7 个答案:

答案 0 :(得分:44)

这有效:

sed -rne 's/(dbservername)\s+\w+/\1 yyy/gip'

(当你使用-r选项时,你不必逃避parens。)

一点解释:

  • -r是扩展的正则表达式 - 对正则表达式的写法有所区别。
  • 除非指定,否则
  • -n不会打印 - 默认情况下会打印sed
  • -e意味着它是一个表达式。让我们打破表达式:
    • s///是搜索替换的命令,第一对之间的匹配是匹配的正则表达式,第二对是替换,
    • gip,它位于search replace命令之后; g表示全局,即每个匹配而不仅仅是第一个匹配将被替换为一行; i不区分大小写; p表示完成后打印(请记住之前的-n标志!),
    • 括号代表匹配部分,稍后会出现。所以dbservername是第一个匹配部分,
    • \s是空格,+表示一个或多个(vs *,零个或更多)出现,
    • \w是一个单词,即任何字母,数字或下划线,
    • \1是GNU sed的特殊表达式,可在随附的搜索中打印第一个括号内的匹配。

答案 1 :(得分:9)

其他人已经提到了括号的转义,但是如果该行的第一部分是常数,为什么还需要一个后向引用呢?

你可以简单地做

sed -e 's/dbservername.*$/dbservername yyy/g'

答案 2 :(得分:2)

你正在逃避你的(和)。我很确定你不需要这样做。尝试:

sed -rne 's/(dbservername)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'

答案 3 :(得分:1)

使用单引号时,不应该逃避事情。即

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername[[:blank:]]+)([[:alpha:]]+)/\1 yyy/gip'

答案 4 :(得分:1)

你不应该逃避你的父母。尝试:

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername)[[:blank:]]+([[:alpha:]]+)/\1 yyy/gip'

答案 5 :(得分:1)

这可能对您有用:

echo "DBSERVERNAME     xxx" | sed 's/\S*$/yyy/'
DBSERVERNAME     yyy

答案 6 :(得分:0)

试试这个

sed -re 's/DBSERVERNAME[ \t]*([^\S]+)/\yyy/ig' temp.txt

或者

awk '{if($1=="DBSERVERNAME") $2 ="YYY"} {print $0;}' temp.txt