Logo Questions Linux Laravel Mysql Ubuntu Git Menu

How can I reorganize nested quotes within sed regex in a bash script that triggers an "unterminated substitute pattern" error?

The following command is throwing an unterminated substitute pattern error in bash:

eval $(echo "sed '" "s,@\("{a..u}{a..z}"\),\n\n\1,;" "'")

But not for everyone. Linux apparently works fine. Mac throws the unterminated substitute pattern error.

How can I reorganize to make this work?

Here's the entire bash command (the goal is to cleanly output current MySQL settings into my.cnf) :

  # Print version, user, host and time
  echo -e "# MYSQL VARIABLES {{{1\n##\n# MYSQL `
      mysql -V | sed 's,^.*\(V.*\)\, for.*,\1,'
      ` - By: `logname`@`hostname -f` on `date +%c`\n##"
  for l in {a..z}; do
      # Get mysql global variables starting with $l
      echo '#'; mysql -NBe "SHOW GLOBAL VARIABLES LIKE '${l}%'" |
      # Transorm it
      sed 's,\t,^= ,' |
      column -ts^ |
      tr "\n" '@' |
      eval $(echo "sed '" "s,@\("{a..u}{a..z}"\),\n\n\1,;" "'") |
      eval $(echo "sed '" "s,@\(innodb_"{a..z}{a..z}"\),\n\n\1,;" "'") |
      tr '@' "\n" |
      sed 's,^,# ,g'
  echo -e "#\n##\n# MYSQL VARIABLES }}}1";
} | tee ~/mysql-variables.log
like image 364
Ryan Avatar asked Mar 18 '23 23:03


2 Answers

The default sed in OS X is an BSD version of sed. Just tested:

  • the above fails in OS X's default sed,
  • and works with the GNU version (gsed - installed from macports).

So, probably the BSD version doesn't handles such long substitution command series.

You can try use the next:

eval $(echo "perl -ple '" "s,@("{a..u}{a..z}"),\n\n\1,;" "'")

And maybe I didn't understand right your goal, but what is a wrong with a much simpler?

sed 's/@\([a-u][a-z]\)/\n\n\1/' #or
sed 's/@\("[a-u][a-z]"\)/\n\n\1/'


Once again i'm only focused to the 1st code-line and not the whole solution. So created a bash/perl version what works without problems on OS X (with default OS X tools).

The next code

MYSQLCMD=/usr/local/mysql-5.6.16-osx10.7-x86_64/bin/mysql   #your path to mysql command

printf "# MYSQL VARIABLES {{{1\n##\n# MYSQL %s " "$($MYSQLCMD -V | sed 's/.*\(Ver .*\),.*/\1/')"
printf " - By: %s@%s on %s\n" $(logname) $(hostname -f) "$(date +%c)"

perl -e "\$s=qx($MYSQLCMD -NBe 'SHOW GLOBAL VARIABLES');" \
     -e 'for("aa".."uz"){$s=~s/^($_)/#\n$1/m;$s=~s/^(innodb_$_)/#\n$1/m};' \
     -e '$s=~s/(.*)\t(.*)/sprintf "# %-55s= %s",$1,$2/gem;print $s'

printf "#\n##\n# MYSQL VARIABLES }}}1\n";

roughly do the same what the original code.

like image 155
jm666 Avatar answered Mar 21 '23 13:03


Try breaking the command up into multiple commands:

 eval "$(printf "sed "; echo "-e 's,@\("{a..z}{a..z}"\),\n\n\1,'")"

But note that sed on OSX also probably doesn't like \n as a newline, so you'll have to do:

$ nl='
$ eval "$(printf "sed "; echo "-e 's,@\("{a..z}{a..z}"\),\\$nl\\$nl\1,'")"

I would strongly recommend finding a better solution. Probably via perl.

like image 20
William Pursell Avatar answered Mar 21 '23 12:03

William Pursell