Take the 2-minute tour ×
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.

we know that we can get the value of a variable using $ sign:

x=3
echo $x
3

Is there other ways that we can use to get the value without using $ sign.

I'm asking this because $ sign is a special character to sed, and I get sed: -e expression #1, char 31: unterminated s' command error when trying to do this:

A=25 #lineNumber
destStr="192.168.1.3 192.168.1.4"
sed ""$A"s/Allow from .*/Allow from $destStr/" -i test2

and it prints the string destStr(not the value) when I use the escape character \:

sed ""$A"s/Allow from .*/Allow from \$destStr/" -i test2

using echo instead of sed:

25s/Allow from .*/Allow from  192.168.1.3
192.168.1.4
/ -i test2
share|improve this question

marked as duplicate by Gilles, vonbrand, polym, Braiam, cuonglm Aug 8 at 1:52

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Which shell are you using? Your first version works just fine for me using bash. –  celtschk Aug 7 at 12:29
    
@celtschk, I'm using bash too. –  Networker Aug 7 at 12:31
2  
Do you get the error with exactly the values you've given? Especially: Does destStr have the literal value string? –  celtschk Aug 7 at 12:33
    
@celtschk,No see Edits –  Networker Aug 7 at 12:35
    
What is the output if you replace sed with echo (but leave the arguments unchanged)? –  celtschk Aug 7 at 12:45

5 Answers 5

up vote 4 down vote accepted

As the final edits revealed, the problem is unrelated to the dollar sign, but is caused by the content of deststr, which is not 192.168.1.3 192.168.1.4 but rather two lines, one containing only 192.168.1.3 and the other containing only 192.168.1.4, both lines bveing terminated with a newline character. That is, the actual command after variable replacement is:

sed "25s/Allow from .*/Allow from  192.168.1.3
192.168.1.4
/" -i test2

Now sed interprets its command line by line, and thus the first command it tries to interpret is:

25s/Allow from .*/Allow from  192.168.1.3

which clearly is an unterminated s command, and thus reported by sed as such.

Now the solution you found, using echo, works because

echo $var

calls echo with two arguments (because the whitespace is not quoted, it is interpreted as argument delimiter), the first one being 192.168.1.3 and the second one being 192.168.1.4; both are forms that are not interpreted further by the shell.

Now echo just outputs its (non-option) arguments separated by a space, therefore you now get as command line:

sed "25s/Allow from .*/Allow from  192.168.1.3 192.168.1.4/" -i test2

as intended.

Note however that for command substitution, instead of backticks you should use $() whereever possible, since it's too easy to get backticks wrong. Therefore the follwing does what you want:

sed "$A s/Allow from .*/Allow from $(echo $destStr)/" -i test2

Note that I also took advantage of the fact that sed allows a space between address and command, to simplify the quoting. In situations where such an extra space is not possible, you can also use the following syntax:

sed "${A}s/Allow from .*/Allow from $(echo $destStr)/" -i test2

Also note that this relies on the fact that the non-space characters in destStr are interpreted neither by the shell, nor by sed if occurring in the replacement string.

share|improve this answer

I have managed to solve my problem using echo with ``:

sed ""$A"s/Allow from .*/Allow from `echo $destStr`/" -i test2

but I'm still want to know if there are other ways to get the value without using $ sign.

share|improve this answer

This is how you can do it within the script:

sed -e "${A}s/Allow from .*/Allow from ${destStr}/" -i test2

Using ${variable} let the bash interpret ${variable}s/... like you want it to.

share|improve this answer

Attempting to actually answer the stated question: "Is there other ways that we can use to get the value without using $ sign."

This isn't in the context of your use case, but you could do something like this:

$SOME_VAR="some value or something"
f() { echo ${!1}; }
some_command `f "SOME_VAR"`

You could use this to avoid using $ in the argument list for sed.

share|improve this answer
    
+1, good to know. –  Networker Aug 7 at 17:29

What about

sed $A's/Allow from .*/Allow from '$destStr'/' -i test2

assuming destStr have no white.

or

echo $A"s/Allow from .*/Allow from $destStr/" | sed -f - -i test2

the second form allow white.

share|improve this answer
    
it didn't work too, both ways didn't work –  Networker Aug 7 at 12:20

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