|
本文介绍了如何在shell中读写mysql数据库。主要介绍了如何在shell 中连接mysql数据库,如何在shell中创建数据库,创建表,插入csv文件,读取mysql数据库,导出mysql数据库为xml或html文件, 并分析了核心语句。本文介绍的方法适用于PostgreSQL ,相对mysql而言,shell 中读写PostgreSQL会更简单些。 1. 连接mysql 数据库 shell中连接数据库的方法很简单,只需要指定用户名,密码,连接的数据库名称,然后通过重定向,输入mysql的语句,如下所示:& r% `# `! \: [. V2 w# {9 b* |
[url=]复制代码[/url]代码如下:0 ~" b# w; k/ v: J
mysql -u USERNAME -p PASSWORD DATABASENAME <<EOF 2>/dev/null1 g- n2 h! T1 G
show databases;
- W2 A+ {! h1 TEOF
5 S) U: g8 H( a( d2 G6 \( V/ x, j" ^; R1 |; `. X
但这并不是一个好办法,任何使用该脚本的用户都能看到该数据库用户的账号和密码,要解决这个问题,可以用mysql 数据库的一个特殊配置文件。mysql 数据库使用$HOME/.my.cnf 文件来读取特殊的启动命令和设置。其中一项设置是由该用户账户发起的mysql 会话的默认密码。要在这个文件中设置默认密码,可以加入下面的内容:, W& O- M l) n1 k- J8 F" X% q
[url=]复制代码[/url]代码如下:, G! Y! d! p* ^/ y: D- L
9 X7 p9 ]( _) S[client]
) u; k1 L& J: x9 X, mpassword = 123456. L3 S' v# Y4 h( s6 }, M# M* A: C
然后,别忘了修改权限:2 b k6 k% h( n3 E
chmod 400 .my.cnf5 r; ~) r, x. x$ `
这样就可以通过脚本访问mysql数据库了,如下所示:
2 |- b% o( z! t! T8 |#!/bin/bash6 r" q: c+ ]$ b# t! X+ `
MYSQL=`which mysql`% s. Z# ?# K) ?+ j- `8 A
$MYSQL test -u root << EOF4 ]3 Z6 l8 {) Q. @- s+ a
show databases;
, t7 t$ {" T+ i' G7 mshow tables;
7 O; u- d2 L; S* A+ B! [) @select * from employees where salary > 4000;
; g" H J! u$ K! BEOF0 o% Z% V" q) `% l/ d( W
+ R* j- x9 X2 h S; t' ?& k$ p
7 ~, C- G2 v9 D y* e, r2. 创建数据库 通过上面的方法连接数据库,再通过重定向输入mysql语句,shell中读写mysql基本就介绍完了。只要把sql语句写对了,通过重定向执行即可,下面来看一个实例:4 `# _" I7 g8 L# X1 l5 e# ~
[url=]复制代码[/url]代码如下:
0 w# K. ^: W, L) k8 F
% ?5 y4 Y. t8 j/ X% m$ s' S#!/bin/bash3 v6 n( ]$ [: ^- ~: t
##############################* _( V% }' n& R5 s X$ i) _/ x
# @file create_db_mysql.sh z/ y! M2 e7 |+ F2 f
# @brief create database and tables in mysql0 W' T% t8 j* `) m7 U" q! A
# @author Mingxing LAI; E* \4 ]/ Z) p l+ o9 U/ q, q6 y
# @version 0.1
& W& s+ P% C5 ~0 X, c* D" m# @date 2013-01-20/ x' W2 y( _; m* o* C5 ` Z
##############################5 V! d" [7 q3 }
USER="root"( z' X! U8 x$ b' z7 M3 T
DATABASE="students"1 k9 }( ^9 K. i7 n7 ?
TABLE="students"
2 W3 h& x/ t8 _######################
' D8 f4 A# f7 O1 ~, [- ~#crate database
# ?& g2 x2 a3 h$ K+ T8 Nmysql -u $USER << EOF 2>/dev/null
3 ^) R' g$ z& l' ^0 E* G f6 b4 q* KCREATE DATABASE $DATABASE
/ \( N" C7 f g% AEOF
- a8 M& ^) d! J1 p- f! u; M[ $? -eq 0 ] && echo "created DB" || echo DB already exists
3 \' k! p) {' L: P/ K* j$ }% i######################; e0 L" p+ R! D4 j6 O) O
#create table
# P- [; V, f2 x+ a! C; Z/ ^mysql -u $USER $DATABASE << EOF 2>/dev/null! f }+ A$ N8 W: o7 K: O" P
CREATE TABLE $TABLE(
# `' Q( o* G8 W7 m3 w7 R1 |: gid int,% p# W4 N8 p8 h( t; f
name varchar(100),3 m( W3 n+ i( [
mark int,6 T9 o9 t1 j7 r0 z7 d- _
dept varchar(4)
5 r! p4 E! H; x# Y- ]( _);
. Y* l) E# U0 Q$ j. ]# dEOF$ V! b1 y( U W7 W7 X
[ $? -eq 0 ] && echo "Created table students" || echo "Table students already exist" 2 t. K, ]7 @& t2 @5 C
######################' g! S7 A0 u' J9 b+ N" p2 _
#delete data
' e. N( V; H" y& Y& Gmysql -u $USER $DATABASE << EOF 2>/dev/null5 T& L R( l# R
DELETE FROM $TABLE;( z: W- `6 k* q' u7 a0 ^2 r, Q- S
EOF8 ^6 p+ y$ T7 [ \% U
6 d" O# y" R8 J6 {1 m这个脚本比较简单,就是几条SQL语句,没什么好解释的,下面来看一下,如何读入csv 文件,然后插入到mysql数据库中。 3. 插入csv 文件 上面创建了一个学生表,表中有学生的学号,姓名,成绩,系别,假设有一个csv文件,内容如下:2 v$ |. l5 k! ?- f3 [" w
[url=]复制代码[/url]代码如下:# {( s3 ] u/ n1 T$ l
$cat data) r5 a, Y( y( k- [
1,Navin M,98,CS4 E1 a$ _" K0 u2 x7 Q8 j
2,Kavya N,70,CS5 I2 P, F6 S3 _: e
3,Nawaz O,80,CS
7 M8 S* b5 i8 R" N" M* @4,Hari S,80,EC
8 {( j; e( v% m7 H5,Alex M,50,EC
$ y8 ^7 e0 @8 ]& w% I- ~6,Neenu J,70,EC
e( o( @/ O/ O4 C/ y& t7,Bob A,30,EC
; _: v. _* f; Y( c8 Z1 c+ C8,Anu M,90,AE& d( Q8 ]7 N) B
9,Sruthi,89,AE- a3 M3 l! \% L2 ~
10,Andrew,89,AE
6 j* \% m# z S& D0 ^; x: w$ D
# }. H6 Q. ~: W- V2 A4 y
* i3 x4 n7 Y9 [ l) F P为了将csv 文件插入到数据库,我们需要逐行读入,然后给字符串加上双引号,最后生成语句如下:5 V+ p/ N1 V. G. R% b% }
[url=]复制代码[/url]代码如下:
* t5 b2 V2 p5 M/ ~! Y
5 ^5 e e/ m, Hinsert into students VALUES(1, "Navin M", 98, "CS");
/ ~$ \7 o7 `3 b& o9 r* o S' x3 k4 i2 b* H
3 P' V+ c5 ^4 d( e+ Y! _: D! B3 r要解析csv 文件,最好的工具莫过于awk了,将域的分隔符指定为逗号-F,,awk就自动将各个域拆分出来了,然后在需要双引号的地方打印输出一个双引号,就能够轻松得到下面这样的数据:
& W+ u5 |/ I8 C- h# K0 N2 Q/ O: M! w% I[url=]复制代码[/url]代码如下:2 h$ m6 H9 V: H5 I8 R' \$ Z1 O
1, "Navin M", 98, "CS" awk 代码如下:
1 K+ ?% z0 t: P3 Q. P2 _query=`echo $line | awk -F, '{ printf("%s,\"%s\",%s,\"%s\"", $1, $2, $3, $4)}'`
# e/ K6 {1 B+ ~( K6 b* S5 Z+ h6 `statement=`echo "INSERT INTO $TABLE VALUES($query);"`
9 [$ j3 p0 X& h+ D& u/ e8 eecho $statement5 R( F+ B. _& w7 D7 M; q% C7 ]
+ ^7 C3 i# y( @8 D" L当然了,你也可以用其他办法,不过,几乎没有比awk更简单的了,第2种方法如下:
/ f2 I! v* ~! z, m[url=]复制代码[/url]代码如下:
/ \2 V, \! W- J( q2 u" t
1 S/ B$ Y, h: Q/ M, i4 n+ O) WoldIFS=$IFS
" F6 _0 [7 p! VIFS=,
) N9 U0 V8 j7 X: x; g; `values=($line)! G& \) E) d" c
values[1]="\"`echo ${values[1]} | tr ' ' '#' `\""
# ]' {# ~. s0 l, bvalues[3]="\"`echo ${values[3]}`\"" query=`echo ${values[@]} | tr ' #' ', '`0 y j/ `& V/ k0 b- C q' U; M
IFS=$oldIFS statement=`echo "INSERT INTO $TABLE VALUES($query);"`
) D4 @2 t* T7 ~5 \; a5 z0 Mecho "$statement"
8 a( |0 r0 X) d- F% E6 W
$ o& Z. ]! ?$ [0 x+ ^& D3 A3 u+ k
首先通过指定域分隔符,将csv文件解析成一个数组,然后将空格替换成一个特殊的符号"#"(因为后面的替换中,会一次性输出数组,而数组是用空格分隔各字段,我们要将分隔数组的空格替换成逗号,所以这里将数据中的空格替换成"#") ,给字符串加上双引号,最后再把空格替换成逗号,把"#"替换为空格。这种方法真是让人抓狂,我第一次就没有看明白,尤其是为什么要将空格替换成"#"。: P h3 @) I) p& F
完整的插入数据的程序如下:
4 q; J+ U% \" m [url=]复制代码[/url]代码如下:
+ @6 T. x7 ^% W/ |9 b
! V2 I4 U& K2 {) b0 Z#!/bin/bash
3 @" c' j* Q+ X$ x#
: Y2 ^0 Y! ]" I3 H) r# @file write_to_db_mysql.sh: v9 n9 O; k: v: h* Q3 W( }
# @brief wirte data to database in mysql
$ h: V; E9 {3 G3 P; @6 R# @author Mingxing LAI& A1 R5 o2 v0 [* H+ y2 ]3 }* {5 e
# @version 0.19 J; f; p; n* w3 e
# @date 2013-01-20! a) K k% H- q1 U, X
#+ q0 U h. h6 w1 u3 D: P2 }$ O
USER="root"
5 X; i% ~* W, w( O5 @DATABASE="students"
/ x, R! Z2 ^& }( A0 s/ Y+ }TABLE="students"7 m/ z c& f' _
if [ $# -ne 1 ]; then; V2 a5 ?2 Y8 i" b$ D
echo $0 DATAFILE$ f0 Q- i+ k% A0 A
echo* Q% L- W0 I* D5 Q7 E0 z3 y" R/ I
exit 2
' C4 f" @' H& }3 k) sfi
l" h8 K: @: g1 I# c& ?# S% {data=$1/ f8 u4 w5 Z3 a5 J9 n& T8 c$ t
while read line;+ ?4 U& d7 j+ O% Y8 t
do
# P8 e( m' e, s4 ^& P1 {# query=`echo $line | awk -F, '{ printf("%s,\"%s\",%s,\"%s\"", $1, $2, $3, $4)}'`# Z& Z$ \% V. m5 R2 y
oldIFS=$IFS2 C7 e0 {& B* Q; o
IFS=,
& q) B8 D& i0 a' T values=($line)4 r' e/ a( a9 W7 J+ {
values[1]="\"`echo ${values[1]} | tr ' ' '#' `\""
2 o" V) v0 o' j- p4 | values[3]="\"`echo ${values[3]}`\""
$ O y5 Y- i* ?& _- A. J+ e4 T query=`echo ${values[@]} | tr ' #' ', '`
: C) ~' U6 u* U1 a IFS=$oldIFS
9 T- J( L6 p$ @5 R) d" Q2 b statement=`echo "INSERT INTO $TABLE VALUES($query);"`$ }0 a5 y! X# [# C6 z% b
# echo $statement mysql -u $USER $DATABASE << EOF
1 ~. C4 E$ p/ H INSERT INTO $TABLE VALUES($query);
9 ^( |; A8 ?: q, a, W; P) b/ m2 sEOF8 L j8 g4 h' j* Y" A g1 e
done < $data
`, Y' L; `+ ]! Q oif [[ $? -eq 0 ]]; then9 o8 H( t% p4 a5 j6 J$ s& d
echo "Wrote data into DB"
, o {+ ?' ]5 m" J' }( Pfi- D& W9 z+ F6 ^6 ~ r- R
4 w; j! R+ d* N9 p1 J: e8 E) ]! ?2 b; u% ^/ u
4. 读取数据 知道怎么在shell 中连接mysql ,也知道了怎么在shell中批量执行sql 语句,读取数据,就没有任何难度了。; I0 N6 c+ V0 s$ M) A( m- H# |
[url=]复制代码[/url]代码如下:& f6 x1 ~9 s3 {1 H+ }
#!/bin/bash2 Y0 [4 R1 p$ B. Y, z
#
! t8 Z2 u0 A6 i# @file read_db_mysql.sh/ M: L: s, f4 F8 \9 K5 v( T
# @brief read data from mysql5 |2 F2 F3 F0 {- d) R6 S
# @author Mingxing LAI, l6 K* q7 k8 l; x1 I( Y6 ?% F7 d
# @version 0.1
& Y; R- y) F* T5 i- b$ N5 b+ I# @date 2013-01-203 ]; Z1 b3 V( j9 u& U
#
% S( |, {6 i3 f7 u: aUSER="root"
; e$ O6 o: ?7 [4 Z4 SDATABASE="students"
# `! G/ e+ K( |7 ?TABLE="students" #用tail 去掉表头& i' p" g5 W* `
depts=`mysql -u $USER $DATABASE <<EOF | tail -n +2
1 D& p' V- J: N0 [1 v7 [+ c, k# b/ sSELECT DISTINCT dept FROM $TABLE;
( ^/ a1 c, J6 L. pEOF` for d in $depts; do
9 k3 V: W# {) S0 t4 Q echo Department: $d G! k9 W$ G9 T, B3 U# ~
result="`mysql -u $USER $DATABASE << EOF
9 E: n: Z, Z! o; X+ f set @i:=0;! B+ J( F8 [7 e8 `6 e: ]3 Z& h
SELECT @i:=@i+1 as rank, name, mark FROM students WHERE dept="$d" ORDER BY mark DESC;
6 @* T. X( w3 hEOF`" echo "$result"
2 c, w5 h6 C. @$ _$ G1 K1 O; Y$ y, Cecho
$ `4 Y- W9 e, X: R& vdone% Y/ ]. M2 q6 f7 ~7 j1 P1 u2 d/ u5 L
9 f6 t, D5 y/ h0 R" D/ o7 k
3 [& }/ G. D* D7 D0 t5 h# ~$ Q- H我们还可以在mysql语句中,使用选项来控制数据的输出格式; J N( C a5 W4 r
-H 输出为html4 ?# G; Q/ W8 _' _. E
-X 输出为xml 如下所示:
: h$ X' ]( W- x% C; ^6 ] [url=]复制代码[/url]代码如下:
. r) _/ b8 f1 A( ?9 T( H
/ k+ Q- u" ^8 W, P- d4 r# B$ L' g#!/bin/bash
. d& x: \4 }6 U2 u/ \. k' eUSER="root"
0 f1 W. y% C0 s% ^DATABASE="students"! ~7 o. O% `: ^
TABLE="students"
D; \* V" S3 X0 Jmysql -u $USER $DATABASE -H << EOF
0 T, [6 V: \8 }select * from $TABLE
1 I* ~; \7 E' g5 E+ O, yEOF
" s7 U; ]3 P, D+ U 7 Z' A+ q8 e. N
6 ~4 E f: A2 i' v W
html 格式的可读性比较差,输出效果如下:6 h4 T. o' T* O- T" e
[url=]复制代码[/url]代码如下:' L8 f2 E5 [/ K+ r3 R1 i
<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>
- r# y( Q e+ j! f& y. b& {% Y+ V1 @
可读性差也可以理解,因为人家觉得,你没必要修改么,直接以html形式展示数据就可以了。: m8 V. ~ }* x; W
[url=]复制代码[/url]代码如下:
' P8 T. s# k+ b1 o* Kid name mark dept
' S$ i( |( K0 {$ R0 T6 r5 K1 q* r1 Navin M 98 CS0 |* ^6 K; m" b e+ z. d
2 Kavya N 70 CS
) s4 ]9 [, ~! N3 Nawaz O 80 CS4 ?2 i( b( @4 p3 g# _: o3 m3 Y0 Y6 A
4 Hari S 80 EC
3 a. h4 N/ k5 A0 p6 H+ t5 Alex M 50 EC
& S4 F* ~" A: k- A, U+ e- |6 Neenu J 70 EC+ Z6 }9 s" Y2 N" C. {! X
7 Bob A 30 EC/ p3 [# b$ H A( _, w) i+ }% G2 |
8 Anu M 90 AE
! J9 r6 K8 H ?: F9 Sruthi 89 AE" P7 u* c9 c, \; K4 r
10 Andrew 89 AE
3 i* [$ x \, w; _- y, H/ ^: H4 r/ s6 N9 y2 ?# [+ g3 D5 \ z# P
# U7 z" g" P* p4 B1 \9 axml形式的数据显示就比较正常了,直接将上面的-H 换成-X,输出如下:8 [8 B {5 S& I
[url=]复制代码[/url]代码如下:
" t# u. R4 [0 E5 {; }& N<?xml version="1.0"?>
1 s8 @7 O: R7 u: A9 k9 S$ Y! J4 c<resultset statement="select * from students" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
$ Z# i9 g _7 {: H: K <row>
9 ?5 N, \: }$ e0 v" o5 O( l <field name="id">1</field>7 W7 M0 i9 y& _8 _
<field name="name">Navin M</field>
5 L' c% E; T) y3 c <field name="mark">98</field>
, a5 ~8 ?0 K( O0 |/ J3 z: T <field name="dept">CS</field> m1 R* ?( D! ?7 t4 s
</row>
) i: V' r: p3 e+ e$ l1 D <row>
4 b$ G. T& T! v% z a( H @ <field name="id">2</field>
2 `# _) S6 w/ K F <field name="name"> Kavya N</field>
( G# u$ o* J( _8 f$ I <field name="mark">70</field>
& [3 l7 p& w2 j <field name="dept">CS</field>& x- D& ]: v8 D
</row>+ z" a- e+ d" `, q# g) o3 _ X
</resultset>
6 I: h* X" T' w6 K: a! L i- V6 f; T: |' q5 o* l4 L
: }) _( }( B9 |' O" A
完。) J W% j2 j# d& p6 ~! ]
|