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. -
-n
does not print unless specified -sed
prints by default otherwise, -
-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, -
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!), - The brackets represent a match part, which will come up later. So
dbservername
is the first match part, -
\s
is whitespace,+
means one or more (vs*
, zero or more) occurrences, -
\w
is a word, that is any letter, digit or underscore, -
\1
is a special expression for GNUsed
that prints the first bracketed match in the accompanying search.
s ///是搜索替换的命令,第一对之间的匹配是匹配的正则表达式,第二对是替换的正则表达式,
gip,它遵循search replace命令; g表示全局,即每个匹配而不仅仅是第一个匹配将被替换为一行;我不区分大小写; p表示完成后打印(记住之前的-n标志!),
括号代表匹配部分,稍后会出现。所以dbservername是第一个匹配部分,
\ s是空格,+表示一个或多个(vs *,零或更多)出现,
\ w是一个单词,即任何字母,数字或下划线,
\ 1是GNU sed的一个特殊表达式,它在随附的搜索中打印出第一个括号内的匹配。
-
-r是扩展的正则表达式 - 对正则表达式的编写方式有所不同。
除非指定-n不打印 - 否则默认打印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. -
-n
does not print unless specified -sed
prints by default otherwise, -
-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, -
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!), - The brackets represent a match part, which will come up later. So
dbservername
is the first match part, -
\s
is whitespace,+
means one or more (vs*
, zero or more) occurrences, -
\w
is a word, that is any letter, digit or underscore, -
\1
is a special expression for GNUsed
that prints the first bracketed match in the accompanying search.
s ///是搜索替换的命令,第一对之间的匹配是匹配的正则表达式,第二对是替换的正则表达式,
gip,它遵循search replace命令; g表示全局,即每个匹配而不仅仅是第一个匹配将被替换为一行;我不区分大小写; p表示完成后打印(记住之前的-n标志!),
括号代表匹配部分,稍后会出现。所以dbservername是第一个匹配部分,
\ s是空格,+表示一个或多个(vs *,零或更多)出现,
\ w是一个单词,即任何字母,数字或下划线,
\ 1是GNU sed的一个特殊表达式,它在随附的搜索中打印出第一个括号内的匹配。
-
-r是扩展的正则表达式 - 对正则表达式的编写方式有所不同。
除非指定-n不打印 - 否则默认打印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