'Use a variable's value in a sed command [duplicate]

I can't seem to use a variable in a sed command, for example:

sed "24s/.*/"$ct_tname"/" file1.sas > file2.sas

I want $ct_tname the variable, not literally $ct_tname, which is what I keep getting.

Anybody know how to get this to work?

The problem is actually more complex and I omitted some information.

ct_fname="%let outputfile="/user/ct_"$1".csv";"

Here, $1 is the argument passed in at the start of my bash script (sed is being run inside a bash script).

This doesn't run successfully, but it does run if I replace ct_fname with

ct_fname="%let table=ct_$1;"

Is there a way to get the first ct_fname to be passed successfully?



Solution 1:[1]

you need to use double quotes (") instead of single quotes ('). single quotes pass their content literally, without translating variables (expansion).

try

sed "24s/.*/\"$ct_tname\"/" file1.sas > file2.sas

btw, if you're going to be editing a file (that is if file2.sas is a temporary file), you should be using ed instead.

Solution 2:[2]

In my case, i just remplaced single quotes by the double ones:

for a in $(cat ext.cnf); do sed -n "/$a$/p" file1 >> file2; done

For now, it's working well...

Solution 3:[3]

The problem is that when $ct_fname is substituted, sed sees extra / separators, so

sed "24s/.*/"$ct_tname"/" file1.sas > file2.sas

becomes

sed "24s/.*/"%let outputfile=/user/ct_ARGUMENT1.csv;"/" file1.sas > file2.sas

and you'll get a sed error because there are 5 / instead of the expected 3.

Instead, change your sed separators to an unused character like | or :, and either single or double quotes will work just fine:

sed '24s|.*|'$ct_tname'|' file1.sas > file2.sas
sed "24s|.*|"$ct_tname"|" file1.sas > file2.sas

Solution 4:[4]

Shell variables are not expanded inside single quotes. Try this instead:

sed "24s/.*/\"$ct_tname\"/" file1.sas > file2.sas

Solution 5:[5]

You need to use double (") quotes, with single (') quotes the value of the variable doesn't get replaced. Since you have double quotes in your replacement text, you need to escape them:

sed "24s/.*/\"$ct_tname\"/" file1.sas > file2.sas

Solution 6:[6]

Other answers focus on the use of escaped double quotes in their examples. Note that this is not always what you want :

$ FOO="auie"; echo foo123bar|sed "s/123/\"$FOO\"/"
foo"auie"bar
$ FOO="auie"; echo foo123bar|sed "s/123/$FOO/"
fooauiebar
$ FOO="auie"; echo fooauiebar|sed "s/\"$FOO\"/123/"
fooauiebar
$ FOO="auie"; echo fooauiebar|sed "s/$FOO/123/"
foo123bar

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 c00kiemon5ter
Solution 2 Garik
Solution 3 Roger Dueck
Solution 4 twalberg
Solution 5 Kenneth Hoste
Solution 6 Skippy le Grand Gourou