sed:替换部分行

时间:2022-04-25 16:49:39

How can one replace a part of a line with sed?

如何用sed替换一部分线?

The line

DBSERVERNAME     xxx

should be replaced to:

应该替换为:

DBSERVERNAME     yyy

The value xxx can vary and there are two tabs between dbservername and the value. This name-value pair is one of many from a configuration file.

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

I tried with the following backreference:

我尝试了以下反向引用:

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

and that resulted in an error: invalid reference \1 on `s' command's RHS.

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

Whats wrong with the expression? Using GNU sed.

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

7 个解决方案

#1


This works:

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

(When you use the -r option, you don't have to escape the parens.)

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

Bit of explanation:

一点解释:

  • -r is extended regular expressions - makes a difference to how the regex is written.
  • -r是扩展的正则表达式 - 对正则表达式的编写方式有所不同。

  • -n does not print unless specified - sed prints by default otherwise,
  • 除非指定-n不打印 - 否则默认打印sed,

  • -e means what follows it is an expression. Let's break the expression down:
    • s/// is the command for search-replace, and what's between the first pair is the regex to match, and the second pair the replacement,
    • s ///是搜索替换的命令,第一对之间的匹配是匹配的正则表达式,第二对是替换的正则表达式,

    • gip, which follows the search replace command; g means global, i.e., every match instead of just the first will be replaced in a line; i is case-insensitivity; p means print when done (remember the -n flag from earlier!),
    • gip,它遵循search replace命令; g表示全局,即每个匹配而不仅仅是第一个匹配将被替换为一行;我不区分大小写; p表示完成后打印(记住之前的-n标志!),

    • The brackets represent a match part, which will come up later. So dbservername is the first match part,
    • 括号代表匹配部分,稍后会出现。所以dbservername是第一个匹配部分,

    • \s is whitespace, + means one or more (vs *, zero or more) occurrences,
    • \ s是空格,+表示一个或多个(vs *,零或更多)出现,

    • \w is a word, that is any letter, digit or underscore,
    • \ w是一个单词,即任何字母,数字或下划线,

    • \1 is a special expression for GNU sed that prints the first bracketed match in the accompanying search.
    • \ 1是GNU sed的一个特殊表达式,它在随附的搜索中打印出第一个括号内的匹配。

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

#2


Others have already mentioned the escaping of parentheses, but why do you need a back reference at all, if the first part of the line is constant?

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

You could simply do

你可以干脆做

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

#3


You're escaping your ( and ). I'm pretty sure you don't need to do that. Try:

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

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

#4


You shouldn't be escaping things when you use single quotes. ie.

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

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

#5


You shouldn't be escaping your parens. Try:

你不应该逃避你的parens。尝试:

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

#6


This might work for you:

这可能对你有用:

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

#7


Try this

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

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

or this

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

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

#1


This works:

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

(When you use the -r option, you don't have to escape the parens.)

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

Bit of explanation:

一点解释:

  • -r is extended regular expressions - makes a difference to how the regex is written.
  • -r是扩展的正则表达式 - 对正则表达式的编写方式有所不同。

  • -n does not print unless specified - sed prints by default otherwise,
  • 除非指定-n不打印 - 否则默认打印sed,

  • -e means what follows it is an expression. Let's break the expression down:
    • s/// is the command for search-replace, and what's between the first pair is the regex to match, and the second pair the replacement,
    • s ///是搜索替换的命令,第一对之间的匹配是匹配的正则表达式,第二对是替换的正则表达式,

    • gip, which follows the search replace command; g means global, i.e., every match instead of just the first will be replaced in a line; i is case-insensitivity; p means print when done (remember the -n flag from earlier!),
    • gip,它遵循search replace命令; g表示全局,即每个匹配而不仅仅是第一个匹配将被替换为一行;我不区分大小写; p表示完成后打印(记住之前的-n标志!),

    • The brackets represent a match part, which will come up later. So dbservername is the first match part,
    • 括号代表匹配部分,稍后会出现。所以dbservername是第一个匹配部分,

    • \s is whitespace, + means one or more (vs *, zero or more) occurrences,
    • \ s是空格,+表示一个或多个(vs *,零或更多)出现,

    • \w is a word, that is any letter, digit or underscore,
    • \ w是一个单词,即任何字母,数字或下划线,

    • \1 is a special expression for GNU sed that prints the first bracketed match in the accompanying search.
    • \ 1是GNU sed的一个特殊表达式,它在随附的搜索中打印出第一个括号内的匹配。

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

#2


Others have already mentioned the escaping of parentheses, but why do you need a back reference at all, if the first part of the line is constant?

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

You could simply do

你可以干脆做

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

#3


You're escaping your ( and ). I'm pretty sure you don't need to do that. Try:

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

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

#4


You shouldn't be escaping things when you use single quotes. ie.

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

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

#5


You shouldn't be escaping your parens. Try:

你不应该逃避你的parens。尝试:

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

#6


This might work for you:

这可能对你有用:

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

#7


Try this

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

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

or this

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

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