Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash Script Loop Through MySQL

Tags:

bash

loops

mysql

I need a bash script that can retrieve MySQL data from a remote data base. Actually I have that done, but what I need it to do now is loop through the records somehow and pass a variable to another bash file. Here's my MySQL call:

mysql -X -u $MyUSER -p$MyPASS -h$MyHOST -D$MyDB -e'SELECT `theme_name`, `guid` FROM `themes` WHERE `theme_purchased`="1" AND `theme_compiled`='0';' > themes.xml
download_themes.sh

It exports the data into an xml file called theme.xml right now, I was just trying to figure out some way to loop through the data. I am trying to avoid PHP and perl and just trying to use bash. Thanks in advance.

like image 415
Brian Leishman Avatar asked May 07 '11 00:05

Brian Leishman


3 Answers

something like:

mysql -e "SELECT `theme_name`, `guid` FROM `themes` WHERE `theme_purchased`='1' AND `theme_compiled`='0'" | while read theme_name guid; do
    # use $theme_name and $guid variables
    echo "theme: $theme_name, guid: $guid"
done

in short: the mysql command outputs record separated by '\n' and fields separated by '\t' when the output is a pipe. the read command reads a line, splits in fields, and puts each on a variable.

if your data has spaces in the fields, you get some problems with the default read splitting. there are some ways around it; but if you're only reading two fields and one of them shouldn't have any spaces (like the guid), then you can put the 'dangerous' field at the end, and read will put everything 'extra' in the last variable.

like this:

mysql -e "SELECT `guid` `theme_name`, FROM `themes` WHERE `theme_purchased`='1' AND `theme_compiled`='0'" | while read guid theme_name; do
    # use $theme_name and $guid variables
    echo "theme: $theme_name, guid: $guid"
done
like image 187
Javier Avatar answered Nov 12 '22 19:11

Javier


Rather than outputting XML, may I suggest you simply use the SELECT INTO OUTFILE syntax or mysql --batch --raw to output tab-separated values. You then have much easier access through bash to the rest of the Unix toolchain, like cut and awk to retrieve the fields you need and reuse them with Bash. No other scripting language is necessary and you needn't mess with XML.

mysql --batch --raw -u $MyUSER -p$MyPASS -h$MyHOST -D$MyDB -e'SELECT `theme_name`, `guid` FROM `themes` WHERE `theme_purchased`="1" AND `theme_compiled`='0';' \
| awk '{print "theme: " $1  " guid: " $2}'
like image 24
Michael Berkowski Avatar answered Nov 12 '22 20:11

Michael Berkowski


The accepted answer does not work when spaces are in the output. It is an easy fix (IFS=$'\t' -- Note the $ -- it is weird):


>mysql ... -BNr -e "SELECT 'funny man', 'wonderful' UNION SELECT 'no_space', 'I love spaces';" | while IFS=$'\t' read theme_name guid; do echo "theme: $theme_name guid: $guid"; done
theme: funny man guid: wonderful
theme: no_space guid: I love spaces

You will, of course, want to substitute your own query.

like image 5
CSTobey Avatar answered Nov 12 '22 21:11

CSTobey