Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to do:

cat update_via_sed.sh | sed 's/old_name/new_name/' > new_update_via_sed.sh

in my program.

But I want to use variables, e.g.


I have tried using them but the substitution doesn't happen (no error). I have tried:

cat update_via_sed.sh | sed 's/old_run/new_run/'
cat update_via_sed.sh | sed 's/$old_run/$new_run/'
cat update_via_sed.sh | sed 's/${old_run}/${new_run}/'
share|improve this question
You can find the answer in Use a parameter in a command argument. – manatwork Mar 25 '13 at 16:00
+1 Thanks man, appreciated. – Michael Durrant Mar 25 '13 at 16:06

You could do:

sed "s/$old_run/$new_run/" < infile > outfile

But beware that $old_run would be taken as a regular expression and so any characters that the variable contains, such as / would have to be escaped. Similarly, in $new_run, the & and \ characters would need to be treated specially and you would have to escape the / and newline characters in it.

share|improve this answer

This worked:

cat update_via_sed.sh | sed 's/'"$old_run"'/'"$new_run"'/'

As I want to 'reuse' the same file I actually use this for anyone wishing a similar approach:

cat update_via_sed.sh | sed 's/'"$old_run"'/'"$new_run"'/' > new_update; mv -f new_update update_via_sed.sh

The above created a new file then deletes the current file than rename the new file to be the current file.

share|improve this answer
You don't need cat, mv, or extra '' unless you're going to have special characters in them. So it's sed -i s/"$old"/"$new"/ update_via_sed.sh. However be aware that this does not work for any value of old and new. e.g. it must not contain / etc., as $old is still a search and $new a replacement pattern where some characters have special meanings. – frostschutz Mar 25 '13 at 16:25
sed -i "s/$old/$new/" is ok too (with the above precautions). sed usually considers the separator to be the first character after the s command - i.e. if your variables contain slashes / but not lets say at (@), you can use "s@$old@$new@". – peterph Mar 25 '13 at 17:23
up vote 3 down vote accepted

'in-place' sed (usng the -i flag) was the answer. Thanks to peterph.

sed -i "s@$old@$new@" file
share|improve this answer
You have the quotes in the wrong place. quotes must be around variables, not s@ (which is not special to the shell in any way). Best is to put everything inside quotes like sed -i "s@$old@$new@" file. Note that -i is not a standard sed option. – Stéphane Chazelas Mar 26 '13 at 14:20
+1 Great. Updated. thx – Michael Durrant Mar 26 '13 at 15:12
how can I escape $ in this command. Like, I am going to change $xxx as a whole to the value of a variable $JAVA_HOME. I tried sed -i "s@\$xxx@$JAVA_HOME@" file, but error says no previous regular expression – hakunami Nov 6 '14 at 8:07

man bash gives this about single quoting

Enclosing characters in single quotes preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

Whatever you type on the command line, bash interprets it and then it sends the result to the program it is supposed to be sent to.In this case, if you use sed 's/$old_run/$new_run/', bash first sees the sed, it recognises it as an executable present in $PATH variable. The sed executable requires an input. Bash looks for the input and finds 's/$old_run/$new_run/'. Single quotes say bash not to interpret the content in them and pass them as they are. So, bash then passes them to sed. Sed gives an error because $ can occur only at the end of line.

Instead if we use double quotes, i.e., "s/$old_run/$new_run/", then bash sees this and interprets $old_run as a variable name and makes a substitution (this phase is called variable expansion). This is indeed what we required.

But, you have to be careful using double quotes because, they are interpreted first by bash and then given to sed. So, some symbols like ` must be escaped before using them.

share|improve this answer

You can use variables in sed as long as it's in a double quote (not a single quote):

sed "s/$var/r_str/g" file_name >new_file

If you have a forward slash (/) in the variable then use different separator like below

sed "s|$var|r_str|g" file_name >new_file
share|improve this answer

Assumed $old_run and $new_run are already set:

cat update_via_sed.sh | eval $(print "sed 's/$old_run/$new_run/g'")

This shows the change on screen. You can redirect output to file if needed.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.