2

I'm using sed to replace a character in a file with a variable. This variable is basically reading the contents of a file or a webpage which contains multiple hash-like strings like below, which are randomly generated:

define('AUTH_KEY',         'CVo|BO;Qt1B|+GE}+h2/yU7h=5`/wRV{>%h.b_;s%S8-p|>qpf]|/Vf@`&[g~*:&');
define('SECURE_AUTH_KEY',  '{G2-<^jWRd7]2,?]6hhM^*asg.2C.+k=gf33-m+ZK_{Mt|q*<ELF4|gPjyxtTh!)');
define('LOGGED_IN_KEY',    'jSNo9Z;5d]tzZoh-QQ`{M-&~y??$R({:*m`0={67=+mF?L.e+R{;)+4}qCAAHz=C');
define('NONCE_KEY',        '19Vt4=%8j/Z-&~ni0S<]9)J^~sy9dh|h9M_RX2#K0]F9+.v+[BP1d&B&}-FTKIJ,');
define('AUTH_SALT',        'jr7f?T|@Cbo]XVAo}N^ilkvD>dC-rr]5{al64|?_Hz }JG$yEi:_aU )Olp YAD+');
define('SECURE_AUTH_SALT', 'hm#Z%O!X_mr?lM|>>~r-?F%wi R($}|9R[):4^NTsj+gS[qnv}7|+0<9e-$DJjju');
define('LOGGED_IN_SALT',   'tyPHBOCkXZh_4H;G|^.&|^#JPB/f;{}y_Orj!6AH?@wovx+KKtTZ A[HMS9SZJ|N');
define('NONCE_SALT',       'Eb-/t 5D-vPV9I--8F<[^lcherGv.g+|7p6;+xP|5g6P}tup1K.vuHAQ=uWZ#}H^');

The variable is defined like so:

KEY=$(cat keyfile)

I used the following sed syntax:

sed -i "s/stringtoreplace/$KEY/" /path/to/file

I've also tried different variations, using single-quotes, quotes around the variables

sed -i "s/stringtoreplace/"$KEY"/" /path/to/file

sed -i "s/stringtoreplace/"${KEY}"/" /path/to/file

sed -i "s/stringtoreplace/'$KEY'/" /path/to/file

I think I "brute-forced" every way possible to put quotes and I don't know how to escape randomly generated characters like those. I keep getting the following error:

unterminated s command

Any suggestions on how to replace the string with the weird-hash-like variable?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
gotgameg
  • 43
  • 4
  • possible duplicate of [Escape a string for sed search pattern](http://stackoverflow.com/questions/407523/escape-a-string-for-sed-search-pattern) – l0b0 Feb 03 '14 at 18:53
  • Possible duplicate of [sed replace with variable with multiple lines](http://stackoverflow.com/questions/6684487/sed-replace-with-variable-with-multiple-lines) – Toby Speight Sep 01 '16 at 10:47

4 Answers4

3

sed is an excellent tool for simple substitutions on a single line but for anything else you should use awk:

awk -v key="$KEY" '{sub(/stringtoreplace/,key)}1' file

That will work no matter what characters "$KEY" contains, except for "&".

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
1

One possibility is to use bash instead of sed. That makes the substitution easy, but you'll have to emulate the -i option.

Something like this:

TMPFILE=$(mktemp)
KEY=$(cat keyfile)
while IFS= read -r LINE; do
  echo "${LINE//stringtoreplace/$KEY}"
done </path/to/file >$TMPFILE
mv $TMPFILE /path/to/file
rici
  • 234,347
  • 28
  • 237
  • 341
0

Try this:

KEY=$(cat keyfile | sed -e 's/[]\/()$*.^|[]/\\&/g')
sed -i "s/stringtoreplace/$KEY/" /path/to/file
Nehal J Wani
  • 16,071
  • 3
  • 64
  • 89
0

The problem is that the $KEY variable contains slashes, which are the delimiters for your s command.

sed can do more than search and replace:

sed '/stringtoreplace/{
     d
     r keyfile
}' /path/to/file

I'm assuming "stringtoreplace" occurs by itself on a line.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 1
    OP - if the slashes are the problem, then you can use a different delimiter for sed. sed uses whichever character follows the initial 's' as the delimiter - people just use the / as a standard. Is there a special character that is guaranteed NOT to show up in your hashes? If so you could use (for example, a colon) 's:stringtoreplace:${KEY}:' – Kevin Feb 03 '14 at 19:03
  • @Kevin, if the data is random as indicated in the question, you'll never know what delimiters are safe. – glenn jackman Feb 03 '14 at 19:11
  • I recommend that approach only if the OP can determine the function that generates the strings, and whether there are any printable characters that cannot be created by that function. That direction may be more work than it is worth. – Kevin Feb 03 '14 at 19:20