30

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?

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
user788171
  • 16,753
  • 40
  • 98
  • 125

6 Answers6

44

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.

c00kiemon5ter
  • 16,994
  • 7
  • 46
  • 48
  • it has come up so many times on S.O. that it should be banned to be answered again :P I think S.O. should prevent a question to be posted, if it finds a similar topic, well, not prevent, but warn before posting that an alike-question is already answered, and have the users check that first before proceeding to post their question. – c00kiemon5ter Jun 21 '12 at 20:28
  • 1
    Actually, my problem is a bit more complex and not fixed by simply changing ' to ", the edited question is above. I think the problem I'm facing is quite challenging and not the common query that comes up on SO regarding this. – user788171 Jun 21 '12 at 21:04
4

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...

Garik
  • 49
  • 1
  • 1
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
Roger Dueck
  • 615
  • 7
  • 16
2

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

sed "24s/.*/\"$ct_tname\"/" file1.sas > file2.sas
twalberg
  • 59,951
  • 11
  • 89
  • 84
1

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
Kenneth Hoste
  • 2,816
  • 20
  • 14
1

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
Skippy le Grand Gourou
  • 6,976
  • 4
  • 60
  • 76