Noel Yap
Noel Yap

Reputation: 19798

With sed or awk, how to replace all occurrences of string between quotes?

Given a file that looks like:

some text
no replace "text in quotes" no replace
more text
no replace "more text in quotes" no replace
even more text
no replace "even more text in quotes" no replace
etc

what sed or awk script would replace all the es that are between quotes and only the es between quotes such that something like the following is produced:

some text
no replace "t@#$xt in quot@#$s" no replace
more text
no replace "mor@#$ t@#$xt in quot@#$s" no replace
even more text
no replace "@#$v@#$n mor@#$ t@#$xt in quot@#$s" no replace
etc

There can be any number es between the quotes.

Upvotes: 0

Views: 1172

Answers (3)

NeronLeVelu
NeronLeVelu

Reputation: 10039

sed ':cycle
s/^\(\([^"]*\("[^"]*"\)*\)*"[^"]*\)e/\1@#$/
t cycle' YourFile
  • Posix version
  • front last till first e
  • change also any e that will be in an unclosed quoted string (at the end thus and failed in next line if that could happend (Not present in your sample)

Upvotes: 0

potong
potong

Reputation: 58488

This might work for you (GNU sed):

sed -r ':a;s/^([^"]*("[^"e]*"[^"]*)*"[^"e]*)e/\1@#$/;ta' file

This regex looks from the start of line for a series of non-double quote characters, followed by a possible pair of double quotes with no e's within them, followed by another possibile series of non-double quote characters, followed by a double quote and a possible series of non-double quotes. If the next pattern is an e it replaces the pattern by the \1 (which is everything up until the e) and @#$. If the substitution is successful i.e. ta, then the process is repeated until no further substitutions occur.

N.B. This caters for lines with multiple pairs of double quoted strings.

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 204258

$ awk 'BEGIN{FS=OFS="\""} {gsub(/e/,"@#$",$2)} 1' file
some text
no replace "t@#$xt in quot@#$s" no replace
more text
no replace "mor@#$ t@#$xt in quot@#$s" no replace
even more text
no replace "@#$v@#$n mor@#$ t@#$xt in quot@#$s" no replace
etc

Also consider multiple pairs of quotes on a line:

$ echo 'aebec"edeee"fegeh"eieje"kelem' |
    awk 'BEGIN{FS=OFS="\""} {gsub(/e/,"@#$",$2)} 1'
aebec"@#$d@#$@#$@#$"fegeh"eieje"kelem

$ echo 'aebec"edeee"fegeh"eieje"kelem' |
    awk 'BEGIN{FS=OFS="\""} {for (i=2;i<=NF;i+=2) gsub(/e/,"@#$",$i)} 1'
aebec"@#$d@#$@#$@#$"fegeh"@#$i@#$j@#$"kelem

Upvotes: 3

Related Questions