Reputation: 192
I have the following lines:
source = "git::ssh://[email protected]/test//bar"
source = "git::ssh://[email protected]/test//foo?ref=tf12"
resource = "bar"
I want to update any lines that contain source
and git
words by adding ?ref:tf12
to the end of the line but inside "
. If the line already contains ?ref=tf12
, it should skip
source = "git::ssh://[email protected]/test//bar?ref=tf12"
source = "git::ssh://[email protected]/test//foo?ref=tf12"
resource = "bar"
I have the following expression using sed, but it outputs wrongly
sed 's#source.*git.*//.*#&?ref=tf12#' file.tf
source = "git::ssh://[email protected]/test//bar"?ref=tf12
source = "git::ssh://[email protected]/test//foo"?ref=tf12?ref=tf12
resource = "bar"
Upvotes: 1
Views: 85
Reputation: 3950
sed '/?ref=tf12"/!s#\(source.*git.*//.*\)"#\1?ref=tf12"#' file.tf
/?ref=tf12"/!
Only run s
ubstitude command if this pattern (?ref=tf12"
) doesn't match
\(...\)"
, \1
Instead of appending to the entire line using &
, only match the line until the last "
. Use parentheses to match everything before that "
into a group which I can then refer with \1
in the replacement. (Where we re-add the "
, so that it doesn't get lost)
Upvotes: 2
Reputation: 189457
Using simple regular expressions for this is rather brittle; if at all possible, using a more robust configuration file parser would probably be a better idea. If that's not possible, you might want to tighten up the regular expressions to make sure you don't modify unrelated lines. But here is a really simple solution, at least as a starting point.
sed -e '/^ *source *= *"git/!b' -e '/?ref=tf12" *$/b' -e 's/" *$/?ref=tf12"/' file.tf
This consists of three commands. Remember that sed
examines one line at a time.
/^ * source *= *"git/!b
- if this line does not begin with source="git
(with optional spaces between the tokens) leave it alone. (!
means "does not match" and b
means "branch (to the end of this script)" i.e. skip this line and fetch the next one.)/?ref=tf12" *$/b
similarly says to leave alone lines which match this regex. In other words, if the line ends with ?ref=tf12"
(with optional spaces after) don't modify it.s/"* $/?ref=tf12"/
says to change the last double quote to include ?ref=tf12
before it. This will only happen on lines which were not skipped by the two previous commands.Upvotes: 2