0

I've read several related posts, but I haven't got my sed string right yet. How can I find the first line that contains myVariable="something", and change what is between the quotation marks to some variable (this is in a shell script)?

I've tried:

sed -i '/myVariable/s/"\([^"]*\)"/"${1}"/' /file

But this inserted $1 into all instances of myVariable="".

If I put "0," before the command like I've seen other posts suggest, then it no longer matches on lines with "myVariable". Instead it replaces the first instance of quotes on every line.

Followup questions: will it make a difference if I want to match a variable with a space in it? What if I want to replace the nth instance of myVariable=""?

Example file.txt:

<blah myVariable="this" />
<blah myVariable="that" />
<blah myVariable="the other thing" />

if I pass in apple to:

sed -i '/myVariable/s/"\([^"]*\)"/"'"${1}"'"/' /file.txt

file.txt becomes:

<blah myVariable="apple" />
<blah myVariable="apple" />
<blah myVariable="apple" />

but I want:

<blah myVariable="apple" />
<blah myVariable="that" />
<blah myVariable="the other thing" />

edit 2:

I tried

sed -i -e '0,/myVariable/s/"\([^"]*\)"/"${1}"/' /file

but that gave me something like:

<foo bar="${1}" />
<blah myVariable="${1}" />
<blah myVariable="${1}" />
<blah myVariable="${1}" />
<alpha bravo="${1}" charlie="notchanged"/>

Note: I don't care about the $1, that can be changed by escaping correctly. I'm more worried that instead of changing the first instance of myVariable, I've now changed the first instance of "" on every single line (regardless of myVariable).

Ryan
  • 2,058
  • 1
  • 15
  • 29
  • Show sample input and your desired output for that sample input. – Cyrus May 01 '15 at 13:20
  • Shell variables don't expand in single quotes. You need to double-quote the variable expansion in the replacement (outside of a single-quoted string): `'/myVariable/s/"\([^"]*\)"/"'"${1}"'"/'` – Etan Reisner May 01 '15 at 13:24
  • Do you have to use `sed` ? I think this is more doable with `perl` . – tivn May 01 '15 at 17:44
  • See http://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed/29626460#29626460 – Ed Morton May 01 '15 at 18:41
  • Thanks I'll read through that link. @tivn, I'd be interested in knowing the perl solution as well. – Ryan May 01 '15 at 19:23
  • seems quite strange. do you use gnu version of sed? with mine one this example works fine: ` $ sed '0,/myVariable/s/"\([^"]*\)"/"'"${test}"'"/' /tmp/file.txt` – Dieselist May 01 '15 at 22:55

3 Answers3

2

Just use awk:

$ awk -v new="apple" '!f && sub(/myVariable="[^"]+/,"myVariable=\""new){f=1} 1' file       
<blah myVariable="apple" />
<blah myVariable="that" />
<blah myVariable="the other thing" />
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
1

This is how we can do that with Perl:

perl -pe 'if (/(myVariable)="[^"]*"/) { s//$1="apple"/ if ++$i==1 }' -i a.txt

This will works whether or not there is whitespace inside the quote pair. For only the n-th regex match, replace 1 in ++$i==1 with n.

tivn
  • 1,883
  • 14
  • 14
0

Break in and out of single quotes

sed -i '/myVariable/s/"\([^"]*\)"/"'"${1}"'"/' /file
RTLinuxSW
  • 822
  • 5
  • 9