43

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

线

DBSERVERNAME     xxx

应改为:

DBSERVERNAME     yyy

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

我尝试使用以下反向引用:

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

这导致了一个错误:'s' 命令的 RHS 上的无效引用 \1。

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

4

7 回答 7

60

这有效:

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

(当您使用 -r 选项时,您不必转义括号。)

一点解释:

  • -r是扩展的正则表达式 - 对正则表达式的编写方式产生影响。
  • -n除非指定,否则不打印 -sed否则默认打印,
  • -e表示它后面是一个表达式。让我们分解表达式:
    • s///是搜索替换的命令,第一对之间是要匹配的正则表达式,第二对是替换,
    • gip,在搜索替换命令之后;g表示全局,即每一个匹配项而不是第一个匹配项将被替换为一行;i是不区分大小写的;p表示完成后打印(记住-n之前的标志!),
    • 括号代表匹配部分,稍后会出现。dbservername第一场比赛也是如此,
    • \s是空格,+表示出现一次或多次(vs *,零或多次),
    • \w是一个词,即任何字母、数字或下划线,
    • \1是 GNU 的一个特殊表达式,sed它在伴随的搜索中打印第一个括号匹配。
于 2009-07-02T14:00:57.643 回答
10

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

你可以简单地做

sed -e 's/dbservername.*$/dbservername yyy/g'
于 2009-07-02T14:22:07.213 回答
2

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

sed -rne 's/(dbservername)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'
于 2009-07-02T13:53:10.047 回答
1

当您使用单引号时,您不应该转义。IE。

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername[[:blank:]]+)([[:alpha:]]+)/\1 yyy/gip'
于 2009-07-02T13:53:43.540 回答
1

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

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername)[[:blank:]]+([[:alpha:]]+)/\1 yyy/gip'
于 2009-07-02T13:54:09.390 回答
1

这可能对您有用:

echo "DBSERVERNAME     xxx" | sed 's/\S*$/yyy/'
DBSERVERNAME     yyy
于 2011-11-17T22:29:16.360 回答
0

试试这个

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

或这个

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

于 2013-01-20T07:26:22.150 回答