how to replace a value with that value + constant

I have a file which has variables from G1 to G229. I want to replace them with G230 to G469; how I can do that? I tried this bash script but it didn’t work:


for num in {1..229}
  echo G$num
  echo G$N  
  sed -i -e 's/$G$num/$G$N/g' file
Asked By: Sadra Avestan


That’s more a job for perl (which GNU sed copied that -i from by the way):

perl -pi -e 's{$GKd+}{
  if ($& >= 1 && $& <= 229) {
    $& + 229
  } else {
  }}ge' file

Note that it would also change G0001 to G230. If you don’t want that, you can change the d+ to [1-9]d*.

With your approach, even if you fixed the quoting, that would rewrite the file 229 times and also not work as you’d wish.

A s/$G1/$G230/g, would change $G12 to $G2302, and the next s/$G2/$G231/g would then change that to G231302 (which the s/$G23/$G252 would change to G2521302 and so on).

Answered By: Stéphane Chazelas

Single quotes in bash stop variable expansion so the following is looking for the literal $G$num to replace with the literal $G$N

sed -i -e 's/$G$num/$G$N/g' file

You want bash expansion to happen so you must use double quotes and escape any special characters manually:

sed -i -e "s/$G$num/$G$N/g" file

You can see the difference with the following script:


for num in {1..229}; do
  echo '$G$num $G$N' vs "$G$num $G$N"


$G$num $G$N vs $G1 $G230
$G$num $G$N vs $G2 $G231
$G$num $G$N vs $G3 $G232
$G$num $G$N vs $G228 $G457
$G$num $G$N vs $G229 $G458
Answered By: Michael Daffin

sed solution. Maybe it too tricky and unoptimal, but it works. As an experiment :).

It do all replacements in the one sed call by executing the one, big command sequence, generated by printf and paste usage. I wanted split this command to the multiline for readability, but couldn’t – it stops working then. So – the oneliner:

sed -i -r "$(paste -d'/' <(printf 's/%s\bn' G{1..229}) <(printf '%s/gn' G{230..458}))" file.txt

It is converting to the following sed command:

sed -i -r "s/G1b/G230/g
s/G229b/G458/g" file.txt


  1. sed -i -r "$(
  2. paste -d'/' – joins left and right parts (which are generated in 3,4 steps) by the slash – / and the result is this: s/G1b/G230/g
  3. <(printf 's/%s\bn' G{1..229}) – makes left parts of the sed substitute command. Example: s/G1b, s/G2b, s/G3b, so on.
    • b – Matches a word boundary; that is it matches if the character to the left is a “word” character and the character to the right is a “non-word” character, or vice-versa. InformationGNU sed, regular expression extensions.
  4. <(printf '%s/gn' G{230..458}) – makes right parts of the sed substitute command. Example: G230/g, G231/g, G232/g, so on.
  5. )" file.txt – input file.



var G1 = value;
G3 = G1 + G2; 
G3 = G1 + G2
G3 = ${G1} + G2
var G2 = value;
var G3 = value;
G224 = G3 + G215;
G124 = G124 + G215;
G124 = G124 + G12;
var G4 = value;
var G5 = value;
var G6 = value;
var G59 = value;
var G60 = value;
var G156 = value;
var G227 = value;
var G228 = value;
var G229 = value;


var G230 = value;
G232 = G230 + G231;
G232 = G230 + G231
G232 = ${G230} + G231
var G231 = value;
var G232 = value;
G453 = G232 + G444;
G353 = G353 + G444;
G353 = G353 + G241;
var G233 = value;
var G234 = value;
var G235 = value;
var G288 = value;
var G289 = value;
var G385 = value;
var G456 = value;
var G457 = value;
var G458 = value;
Answered By: MiniMax
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.