3

I have a line in my.cnf file

datadir = /var/lib/mysql

The following changes it to mysql3307 as expected.

sed -i 's/\/var\/lib\/mysql$/\/var\/lib\/mysql3307/' /etc/my.cnf

But if I have the following:

datadir = /var/lib/mysql/

Then the following does not change the path as expected:

sed -i 's/\/var\/lib\/mysql\/$/\/var\/lib\/mysql3307/' /etc/my.cnf

I want to change the path to mysql3307 where datadir is /var/lib/mysql (with or without /)

Update:

Here is the issue: Both the above commands works on one server and none of them works on another.

The following works as expected, but I need to add that $ to indicate the lines ending with mysql/

sed -i 's/\/var\/lib\/mysql\//\/var\/lib\/mysql3307/' /etc/my.cnf

Observed:

The carot sign ^ works as expected, but end of line sign $ does not. Any clue?

Update:

It seems to be working after using "dos2unix" command.

shantanuo
  • 31,689
  • 78
  • 245
  • 403
  • 2
    When using sed on strings with '/'s in them (eg file paths) you might want to use something else as the delimiter, like ':'. `sed -i 's:/var/lib/mysql$:/var/lib/mysql3307:' /etc/my.cnf` is a bit nicer to read :) – Cam Jackson Jun 23 '11 at 05:27
  • I'm not really sure what the problem is? I echoed your second example string into your second example sed and got `datadir = /var/lib/mysql3307` – Cam Jackson Jun 23 '11 at 05:37
  • Yes. The question is wrong. Actually none of them work on one server and both the commands work on another! – shantanuo Jun 23 '11 at 06:06

3 Answers3

2

If your intent is to only change paths that have that specific directory, you need to be a bit trickier. You have to catch it at the end of a line without the trailing / and you also have to catch it everywhere it has the trailing / (end of line or not).

But you don't want to catch things like /var/lib/mysqlplus since that's a totally different directory.

Consider using extended regular expressions, and using a different separator character so you command doesn't look like sawteeth (/\/\/\/\/\/\/\/\). With those changes, and a small modification to the regular expression itself, it works fine:

$ echo '
/var/lib/mysqlplus
/var/lib/mysql/
/var/lib/mysql
/var/lib/mysql/xyz' | sed -E 's|/var/lib/mysql([$/])|/var/lib/mysql3307\1|'

/var/lib/mysqlplus
/var/lib/mysql3307/
/var/lib/mysql
/var/lib/mysql3307/xyz
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
1

The use of $ as a literal character may need to be escaped, but not as an anchor meaning the end of the string.

BTW, your regex would be a lot easier to read if you used a different delimiter, so you didn't have escape the / in the regex

sed -i `'s|/var/lib/mysql/|/var/lib/mysql13307/|' /etc/my.cnf
pavium
  • 14,808
  • 4
  • 33
  • 50
0

If you specifically want to change just the datadir value, the following command is more reasonable:
sed -i.bak 's| *datadir *=.*|datadir = /var/lib/mysql3306/|g' /etc/my.cnf

Note: -i.bak the backup of the original file with suffix .bak before making the change.

ssapkota
  • 3,262
  • 19
  • 30