|
本文介绍了如何在shell中读写mysql数据库。主要介绍了如何在shell 中连接mysql数据库,如何在shell中创建数据库,创建表,插入csv文件,读取mysql数据库,导出mysql数据库为xml或html文件, 并分析了核心语句。本文介绍的方法适用于PostgreSQL ,相对mysql而言,shell 中读写PostgreSQL会更简单些。 1. 连接mysql 数据库 shell中连接数据库的方法很简单,只需要指定用户名,密码,连接的数据库名称,然后通过重定向,输入mysql的语句,如下所示:
1 V7 c1 e2 k7 n' L) w [url=]复制代码[/url]代码如下:% `% F, D( l* j/ l+ ?1 p# _+ S z
mysql -u USERNAME -p PASSWORD DATABASENAME <<EOF 2>/dev/null& a/ U- P$ v! l0 U
show databases;: S7 A! A( d9 J) @1 N
EOF6 Y4 Z3 t% E, y* E) x
8 {$ i" A/ ?' z但这并不是一个好办法,任何使用该脚本的用户都能看到该数据库用户的账号和密码,要解决这个问题,可以用mysql 数据库的一个特殊配置文件。mysql 数据库使用$HOME/.my.cnf 文件来读取特殊的启动命令和设置。其中一项设置是由该用户账户发起的mysql 会话的默认密码。要在这个文件中设置默认密码,可以加入下面的内容:) h7 R, {$ @. F M4 R( m
[url=]复制代码[/url]代码如下:
R! g/ s, M* j2 l2 {0 B# z9 ~ n/ l# L; D# Y- X8 e
[client]1 S3 I/ \$ Z* |
password = 123456 o6 P& ^6 }% ~. @ y9 h
然后,别忘了修改权限:
6 ?2 O+ {$ s- @# rchmod 400 .my.cnf& X9 K4 ^* I, y2 q! K7 Q$ [1 \
这样就可以通过脚本访问mysql数据库了,如下所示:* ]1 ^% ]& @0 b; N: L6 D9 R
#!/bin/bash
: f* v. s Z7 n; dMYSQL=`which mysql`
9 J7 `! e/ `$ j6 ]$ |% B1 ?$MYSQL test -u root << EOF+ v4 t" E* p) H& [$ ?) |/ o. O' k
show databases;
; M& s: a1 z' `show tables;
4 y, X7 Z, \/ {9 {1 k: o; C8 Zselect * from employees where salary > 4000;" S" V }+ S: v/ c3 `0 P1 C @
EOF9 Q- y7 n4 i/ ?
5 v- A2 v( g3 x( `$ ]
! h% b# Y, ?+ ^5 S
2. 创建数据库 通过上面的方法连接数据库,再通过重定向输入mysql语句,shell中读写mysql基本就介绍完了。只要把sql语句写对了,通过重定向执行即可,下面来看一个实例: W" I9 R7 {& N1 B
[url=]复制代码[/url]代码如下:' g# u1 x" x% @; t7 \
4 }7 z* k$ M0 t( p; m/ O4 i3 R
#!/bin/bash: X! M1 P( ]& K
##############################
7 Z" A2 _; \ a+ T+ s' K# @file create_db_mysql.sh
3 F4 v( O; w7 l* n, ~% r# @brief create database and tables in mysql
`/ ^' Y+ [0 T# @author Mingxing LAI
9 U: L/ N* D" p# J# @version 0.18 i* I p+ X" F7 \6 i- x
# @date 2013-01-20+ ^& M: i. I g7 P9 n
##############################% }' t2 |1 F& x% q s2 Q
USER="root"
+ E$ ^( f# ?; |- bDATABASE="students"" \$ P) y0 ^4 m# R. V4 g
TABLE="students"* p7 u; i# g8 `: }) r; C
######################
, ~9 _; D" |4 Z& N# H#crate database- [% p% X! Q3 ^/ T$ W! g
mysql -u $USER << EOF 2>/dev/null
, i p- Y9 r) k5 \CREATE DATABASE $DATABASE$ n5 g2 u5 S0 H! B1 d/ \6 ?) D
EOF
# C: t7 a: g1 H8 x2 l[ $? -eq 0 ] && echo "created DB" || echo DB already exists
- a( V: S0 {. }% ~; y######################: L7 e* V; j, u9 D
#create table
" l* y9 o, s \mysql -u $USER $DATABASE << EOF 2>/dev/null
$ I6 S# ]) X, Y/ i6 a5 v7 O8 sCREATE TABLE $TABLE(" f6 ?# _/ n2 l
id int,
* F+ k5 M. Y4 A; {name varchar(100),9 t& f0 M$ _, O& D
mark int,! i& q9 ~7 ?$ Y5 U% ]$ p
dept varchar(4) ]6 @5 F" g7 o+ I2 @3 @
);
" p q: K1 a9 f6 CEOF
$ y) N8 s+ s. f8 s5 N[ $? -eq 0 ] && echo "Created table students" || echo "Table students already exist"
I: N" o. J9 i& f0 [######################. A, Y% C) W! y# e
#delete data
6 d; K- f' A4 V% \$ v: X2 hmysql -u $USER $DATABASE << EOF 2>/dev/null5 m0 k; i7 y; u1 i5 z" n
DELETE FROM $TABLE;7 I; j8 K; ?! x5 n' E
EOF, u% g& H/ Y9 O$ ?5 f6 W" Q. C
( d( Z3 g$ u% U
这个脚本比较简单,就是几条SQL语句,没什么好解释的,下面来看一下,如何读入csv 文件,然后插入到mysql数据库中。 3. 插入csv 文件 上面创建了一个学生表,表中有学生的学号,姓名,成绩,系别,假设有一个csv文件,内容如下:. i/ ^) ^9 L6 d. I* d
[url=]复制代码[/url]代码如下:
- H" _/ `9 r3 {& \9 a7 g6 T" }9 U$cat data
( R$ n2 E1 b- j: {4 _5 J1,Navin M,98,CS! `& V+ Z+ V; T: X U: l) n( z
2,Kavya N,70,CS
6 Y! O- p6 T. c6 T& J) m3,Nawaz O,80,CS: S' u: K* ^+ V. b; p/ f/ y5 Z4 C' j& m
4,Hari S,80,EC
/ Z2 ^2 _0 r8 t0 v1 {3 f: @5,Alex M,50,EC( w; l/ H( P; a7 S5 J
6,Neenu J,70,EC% J4 J, I5 ?5 P, i4 `1 `- s
7,Bob A,30,EC2 p/ J, z; d* J: A& }
8,Anu M,90,AE
& [: k- A& Z) i' P+ q7 p* P6 c# B9,Sruthi,89,AE- p3 e& f' ]$ I/ l8 [
10,Andrew,89,AE8 m U2 n+ @8 _$ c. @* m; l
2 c- R" t+ R2 M( p. E' ]% e+ @; @
为了将csv 文件插入到数据库,我们需要逐行读入,然后给字符串加上双引号,最后生成语句如下:1 Y1 b, o0 q) j' S
[url=]复制代码[/url]代码如下:4 R( d8 L( Z( x; }
# R3 s3 R1 I/ j8 [) ^
insert into students VALUES(1, "Navin M", 98, "CS");
. v* | {# C3 A5 g% \( |5 z/ w K7 `9 p7 R* c. Y
% j! V6 u1 u7 B/ a' }% t
要解析csv 文件,最好的工具莫过于awk了,将域的分隔符指定为逗号-F,,awk就自动将各个域拆分出来了,然后在需要双引号的地方打印输出一个双引号,就能够轻松得到下面这样的数据:. g2 M/ ^) m4 m
[url=]复制代码[/url]代码如下:9 Z, X% J- m* u6 j$ b. e: b# Y& n
1, "Navin M", 98, "CS" awk 代码如下:" n: W U! L. b6 D$ D7 J! ~
query=`echo $line | awk -F, '{ printf("%s,\"%s\",%s,\"%s\"", $1, $2, $3, $4)}'`
4 I& a# p. X- H/ g$ E& sstatement=`echo "INSERT INTO $TABLE VALUES($query);"`
* a; Z1 r% P* X7 P* f- kecho $statement8 P: t% i: s/ ]$ @/ a9 b7 `
6 s2 ]0 E% X1 B当然了,你也可以用其他办法,不过,几乎没有比awk更简单的了,第2种方法如下:
/ ^( U. L1 q& A) y" ^1 s[url=]复制代码[/url]代码如下:
8 B: x, ]3 e: u
+ K% ?& R1 |6 EoldIFS=$IFS7 b( M* F( D1 z" {( [- J
IFS=,& a/ M% t0 I* g8 K9 q
values=($line)
& q) k! `9 e0 uvalues[1]="\"`echo ${values[1]} | tr ' ' '#' `\""8 m: |" U9 L8 ^5 c+ c: l. N; G
values[3]="\"`echo ${values[3]}`\"" query=`echo ${values[@]} | tr ' #' ', '` a% ?' ~5 c! M) }9 B3 { w' a
IFS=$oldIFS statement=`echo "INSERT INTO $TABLE VALUES($query);"`
; v8 ~# K6 n4 P: ?% Q* kecho "$statement"
. e1 Z9 }6 X$ J$ |. U& ?
: F B; ^, I( X+ a
" J5 h/ P- K ?6 w/ i$ ]! a首先通过指定域分隔符,将csv文件解析成一个数组,然后将空格替换成一个特殊的符号"#"(因为后面的替换中,会一次性输出数组,而数组是用空格分隔各字段,我们要将分隔数组的空格替换成逗号,所以这里将数据中的空格替换成"#") ,给字符串加上双引号,最后再把空格替换成逗号,把"#"替换为空格。这种方法真是让人抓狂,我第一次就没有看明白,尤其是为什么要将空格替换成"#"。: ~' m% A$ q5 Y. x
完整的插入数据的程序如下:+ o @' H5 j2 o/ w) h( c
[url=]复制代码[/url]代码如下:5 \$ d# j2 h4 l+ x! D
2 f, j7 U$ x# y) M#!/bin/bash8 Y8 W* C) k9 B! S
#
- e( [7 @( B6 t9 r# @file write_to_db_mysql.sh
% N0 H1 d1 `3 l" F+ M6 m# @brief wirte data to database in mysql# W3 @+ x2 B# Q9 {+ |4 L
# @author Mingxing LAI
$ B/ U. O( P% S! m0 ]# @version 0.1
* F0 y5 H% `/ S% r+ [# @date 2013-01-20
8 \ C1 D* T u& `: U* X$ |7 @2 ~#7 l3 r# C% O8 u* H% p: N& g$ W
USER="root"
; q+ B' `+ B3 c( K# e3 K1 RDATABASE="students", `' J* `" N, g2 `3 V. y7 H& o
TABLE="students"5 u' v% l) C: l/ n H* x
if [ $# -ne 1 ]; then9 v' C$ {' L4 Q
echo $0 DATAFILE
; m! z! U6 {6 E, r1 k echo) g7 a9 S2 D6 S% c" z
exit 2
& q4 S. I1 R. v# E" h8 `fi
9 \* y# `% V) ~( N5 | F* S5 J: rdata=$1% s9 f/ T! ~ ~$ r5 R j* k
while read line;! e/ |7 X, |9 J8 w1 {( i; j
do
7 W; f" \0 D8 @) `" D6 X: T8 R# query=`echo $line | awk -F, '{ printf("%s,\"%s\",%s,\"%s\"", $1, $2, $3, $4)}'`
& Q z( D" @1 O5 n oldIFS=$IFS6 u: e+ Y2 o9 p
IFS=," t9 V$ ?8 s2 T# G! e2 E. m6 E
values=($line)
! ?. ~7 A2 W1 J values[1]="\"`echo ${values[1]} | tr ' ' '#' `\""
Z& }3 \2 y9 \; @3 q) @- [ values[3]="\"`echo ${values[3]}`\""2 r" `' p) `% ?
query=`echo ${values[@]} | tr ' #' ', '`
. F5 v7 f5 G. o IFS=$oldIFS
9 X/ g! V9 P* b' Z4 [+ w% B statement=`echo "INSERT INTO $TABLE VALUES($query);"`9 n# c+ n5 m; I6 {
# echo $statement mysql -u $USER $DATABASE << EOF y* q( H0 W- |) v* V
INSERT INTO $TABLE VALUES($query);& Z6 R' ~( J Y! V
EOF; U. C# y$ J" |
done < $data
E" D4 O) T& \5 L$ F! V+ F% ]if [[ $? -eq 0 ]]; then
% M: D8 Z7 y; g echo "Wrote data into DB": D$ E% ]& |8 E) |- e1 t+ I$ g
fi: E; S' k6 P8 N
) A9 @( v3 K3 W: u
3 S. `" y6 }# f% |4. 读取数据 知道怎么在shell 中连接mysql ,也知道了怎么在shell中批量执行sql 语句,读取数据,就没有任何难度了。
- V4 ]: F) K' u& L& l [url=]复制代码[/url]代码如下:) `! {+ o. R, C0 T* ^
#!/bin/bash; k" F" m( J1 t9 n4 r6 S
#
' E" k$ V# ]6 I) n' j2 w# @file read_db_mysql.sh
& }7 r3 P+ [! j1 n' w# @brief read data from mysql
! _% H3 g* y: b" u8 U# @author Mingxing LAI
! @1 ^$ _1 f# b! \* ?4 v, c* k/ N# @version 0.1' T& T' U2 z8 M! w' S3 B
# @date 2013-01-20
/ d: d" m: S& w9 O#
$ _' @) C/ E# l( a9 g3 Y) nUSER="root"7 r8 \1 J6 d- r
DATABASE="students"
+ K% `+ E; r v" d: wTABLE="students" #用tail 去掉表头
, }) {5 T3 ~4 N0 T8 l$ zdepts=`mysql -u $USER $DATABASE <<EOF | tail -n +2
9 J+ [8 v, U. p$ ~5 T5 t0 p% FSELECT DISTINCT dept FROM $TABLE;" _* V& G$ I; l
EOF` for d in $depts; do. o, z3 a3 P: t3 P, |
echo Department: $d+ x; P: o5 |/ f4 L9 E7 m0 u8 E
result="`mysql -u $USER $DATABASE << EOF
" f) G; X( m g9 |! ~1 f set @i:=0;
" s! I" R* ?* {9 w4 L SELECT @i:=@i+1 as rank, name, mark FROM students WHERE dept="$d" ORDER BY mark DESC;
( m% S' O g* V lEOF`" echo "$result"
2 ?( q) f: C$ U! ~echo 4 @6 i% B$ n1 u( }2 j* v$ w
done! A: C* k8 O$ l8 [9 ]
/ E6 U& P2 a0 s& F1 Q- @
, E; l5 E8 Q9 a) M/ E我们还可以在mysql语句中,使用选项来控制数据的输出格式
' H$ N& x, K8 g0 S) ?& ]6 S -H 输出为html2 l6 c! c& u- G7 M! q# N
-X 输出为xml 如下所示:
2 J* V. E8 U+ T, r% J2 ^* {7 b [url=]复制代码[/url]代码如下:
/ M! r5 E7 M% X& F6 U n( l5 M5 \: V' J5 N
#!/bin/bash
. Z5 z3 z$ g) a0 mUSER="root"
$ T' W1 T r0 ?9 I' E0 Q9 w `) n3 mDATABASE="students"
" B) t) x, {! s* B; k3 V* }TABLE="students"
- W' g) k1 F8 [2 R Gmysql -u $USER $DATABASE -H << EOF: T& Y$ x" c, x# N; \% y
select * from $TABLE9 ^3 ]7 D: b. X! q6 a0 H
EOF k# D% P1 b; J5 m5 n) u
3 V m- N, R6 T
+ a0 w I- v- q+ _* m1 T- \* [3 Phtml 格式的可读性比较差,输出效果如下:8 k T" V: |& }4 s$ C' |
[url=]复制代码[/url]代码如下:
! r* f. }: ~$ U8 x; B<TABLE BORDER=1><TR><TH>id</TH><TH>name</TH><TH>mark</TH><TH>dept</TH></TR><TR><TD>1</TD><TD>Navin M</TD><TD>98</TD><TD>CS</TD></TR><TR><TD>2</TD><TD> Kavya N</TD><TD>70</TD><TD>CS</TD></TR><TR><TD>3</TD><TD> Nawaz O</TD><TD>80</TD><TD>CS</TD></TR><TR><TD>4</TD><TD>Hari S</TD><TD>80</TD><TD>EC</TD></TR><TR><TD>5</TD><TD>Alex M</TD><TD>50</TD><TD>EC</TD></TR><TR><TD>6</TD><TD>Neenu J</TD><TD>70</TD><TD>EC</TD></TR><TR><TD>7</TD><TD>Bob A</TD><TD>30</TD><TD>EC</TD></TR><TR><TD>8</TD><TD>Anu M</TD><TD>90</TD><TD>AE</TD></TR><TR><TD>9</TD><TD>Sruthi</TD><TD>89</TD><TD>AE</TD></TR><TR><TD>10</TD><TD>Andrew</TD><TD>89</TD><TD>AE</TD></TR></TABLE>
9 a$ M8 `9 b, ~
; C$ `' V1 Z! W可读性差也可以理解,因为人家觉得,你没必要修改么,直接以html形式展示数据就可以了。4 f4 n4 B2 ?6 K; Q$ S, t$ b9 b. K
[url=]复制代码[/url]代码如下:
3 S7 [" d! G& ~/ p( g8 q- tid name mark dept
$ H. K S: S- ^* |4 W7 G1 Navin M 98 CS2 J. f0 X, ^: }% Y; N' j+ K! ^
2 Kavya N 70 CS
/ J. Z5 ~6 L. C0 m# z% N3 Nawaz O 80 CS' V2 N3 O5 G* C* p8 ?
4 Hari S 80 EC$ `4 o$ o U Q1 v3 g
5 Alex M 50 EC1 `# s* l- l: n* L
6 Neenu J 70 EC* I: J# J1 W: e. m9 _$ P
7 Bob A 30 EC8 }. U m2 @# ?
8 Anu M 90 AE
- `' n; \0 j4 ^( @' X. ?0 e7 i9 Sruthi 89 AE
7 r/ y! x" [* A: C, I10 Andrew 89 AE
; ?2 P) q2 N3 A S$ y0 c
7 y4 U( D6 z8 y6 n2 O* m# l7 a' v- ^# l% `* n' v! h
xml形式的数据显示就比较正常了,直接将上面的-H 换成-X,输出如下:2 s8 s7 I2 g( r% p9 f" u
[url=]复制代码[/url]代码如下:
; T! H1 q4 O0 q- j! d" Y3 ~<?xml version="1.0"?>
, `2 i% ^& v( z; t7 `+ U<resultset statement="select * from students" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
; F. s( n) ]6 b& X* F5 ` <row>8 A2 k3 E+ f( v, B' L! H
<field name="id">1</field>
5 p/ l0 o3 |( ]" a0 S% h$ y <field name="name">Navin M</field>
1 o9 H. ^. m! ~6 v <field name="mark">98</field>
s! M+ [; e2 Z3 q0 v <field name="dept">CS</field>* F, F; i& |% a) X
</row>
: K1 G8 l m F" D7 j8 v <row>: ]/ ^# o! e5 A: b1 e8 S7 w
<field name="id">2</field>
' w$ N1 d% c) R* t/ ^ <field name="name"> Kavya N</field>
: Z% o6 r+ N; J4 @ <field name="mark">70</field>
6 H4 f7 n7 ~) K6 w; q6 y+ f <field name="dept">CS</field>
|7 n) U! d% v0 R! ^" ~7 b </row>6 b6 x6 w* p6 B( E
</resultset>* W/ @( o0 N. S' W0 L, F4 W2 X
0 g" ^" t* u! N6 w( D4 {
& G, |9 e, P3 H H完。
( T& k5 @5 d1 C d, D |