1

I am trying to replace a string in a file on a remote server:

ssh $login "
replacement=\`find . -name file\`;
sed -i -e 's/contact/\$replacement/g' path/file;
"

but I can't get the content of the $replacement variable to be used by sed. The example above prints $replacement in my file. I also tried

sed -i -e 's/contact/\"\$replacement\"/g' path/file;

but it just prints "$replacement"

What would be the correct syntax?

2
  • 1
    Probably relevant: Variable expansion and quotes within quotes. Commented Feb 13, 2019 at 22:37
  • You are using single quotes around the whole sed expression, including the variable expansion. This will prevent the shell from expanding your variable. Could you confirm that you want to replace the string contact in some file with the pathnames of a set of files?
    – Kusalananda
    Commented Feb 13, 2019 at 23:03

2 Answers 2

1

The problem is that in between single quotes $replacement isn't expanded.

In this case sed -i -e "s/contact/$replacement/g" path/file; should work.

Or this:

sed -i -e 's/nothing/'$replacement'/g' path/file;

Example:

$ echo "There's nothing there." > file 
$ cat file 
There's nothing there.
$ replacement=something 
$ sed -i -e 's/nothing/'$replacement'/g' file;
$ cat file
There's something there.

In response to Kusalananda's comment below: If replacement, being a path, contains slashes then you would have to pre-process it before you use it with sed:

replacement=$(sed 's@\/@\\\/@g' <<< "$replacement")
4
  • 2
    Note that $replacement may be a pathname, i.e. it may (will!) contain slashes. Also, you should demonstrate running this on a remote machine using ssh. Using localhost for testing would be enough.
    – Kusalananda
    Commented Feb 13, 2019 at 22:36
  • So then there's a need to pre-process the replacement: replacement=$(sed 's/\//\\\//g' <<< "$replacement") or replacement=$(sed 's|\/|\\\/|g' <<< "$replacement")
    – Arjen
    Commented Feb 13, 2019 at 22:53
  • sed can use almost any other character as delimiter instead of / in a substitution. sed 's@PATTERN@REPLACEMENT@', for example. The only thing is to make sure it's not a character already in the pattern, or in the replacement.
    – Kusalananda
    Commented Feb 13, 2019 at 22:55
  • That's better. The @ is certainly more readable than the | adjacent to the \.
    – Arjen
    Commented Feb 13, 2019 at 22:59
1

here documents are a good idea to explore when you're in quoting hell:

ssh "$login" <<'END_REMOTE'
    replacement=$(find . -name file)
    sed -i -e 's/contact/$replacement/g' path/file
END_REMOTE

The opening keyword for the heredoc is quoted, which means the whole heredoc is single quoted. Easier to read, no?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .