Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed: Replace part of a line

Tags:

sed

How can one replace a part of a line with 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.

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.

Whats wrong with the expression? Using GNU sed.

like image 567
calvinkrishy Avatar asked Jul 02 '09 13:07

calvinkrishy


2 Answers

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.)

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 GNU sed that prints the first bracketed match in the accompanying search.
like image 147
Jeremy Stein Avatar answered Sep 24 '22 11:09

Jeremy Stein


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' 
like image 44
Vicky Avatar answered Sep 21 '22 11:09

Vicky