目录
前言
方法一
方法二
一行命令解决标题需求
命令分段解释
今天想把SQLite里的数据转储到MySQL中,SQLite数据在本地,MySQL在远程服务器的Docker环境中。当时没想着纯靠GUI完成转储操作,结果就按照以下步骤折腾了老久。
到最后一步就犯难了。因为有几十个sql文件,source命令也不支持直接执行某目录下的所有sql文件,或者通配符执行多个sql文件,只能接受一个文件路径参数。source帮助原文就是这么说的:
source (\.) Execute an SQL script file. Takes a file name as an argument.
本来吧,老老实实一个个文件路径输入,把几十个表的数据导入到数据库里也不是多麻烦的事情,但是我呢就是单纯觉得这样做好繁琐,就想着网上有没有什么好的解决方案。
结果翻了几个博文,都是这么一种思路,写一个shell,建立一个for循环,遍历sql文件存放目录,拿到文件名后,使用echo拼接“source xxx.sql”输出到all.sql文件里,最后mysql命令行里执行all.sql文件就ok了。如下图所示:
#!/bin/bash
dir=`ls ~/tmp/` #定义遍历的目录,这个是你sql的存放路径echo "" > all.sql #创建一个总的sql文件,注意别跟你现有的重名即可!
for i in $dir
do
echo "source ~/tmp/$i;" >> all.sql
done
mysql > source ~/tmp/all.sql;
还有个加强版的直接调用mysql命令行工具执行拼接好的命令,那一脚本就完成所有事情了。
这其实就很省事了,但是我就非得自找麻烦。当时就想着以前使用过很多次,仅仅使用一行shell解决了很多事情,感觉无所不能的awk命令,也许能写一行解决现在的需求。
但是awk对我来说实在过于复杂,不看教程实例,很多用法都记不住。不过awk能把其他命令的多行标准输出,作为输入,做一些转换再输出,甚至里面还能执行子命令这我还是能记住的,所以我就想折腾一下。
然而,想起以往子命令嵌套转移那写法实在过于复杂缺乏简洁易懂的关系,于是又想了一下,结合xargs命令,也许就能做到了。xargs在我印象里作用也是跟awk类似,可以把一条命令的标准输出,作为参数传递给另外的命令。结果经过我的不懈努力,总算是把命令给写出来了,这就是我这个小菜鸡苦恼已久的方法二。
cd /root/sql && ls *.sql|awk '{print "'\''source " $0 "'\''"}'|xargs -L 1 -t mysql -u gogs gogs -e
命令看起来有点长,但还是挺好懂的,以管道符“|”分开几段结合来说。
第一段这是先进入/root/sql目录,这个目录就是我存放sql文件的目录,然后呢通过ls列出所有文件名后缀为sql的文件。为方便理解直接贴出 cd /root/sql && ls *.sql输出结果:
第二段是通过管道符把第一段输出的每一行文件名作为awk的输入数据,接着通过内置的print函数打印拼接myql的source命令的语句块。为方便理解直接贴出cd /root/sql && ls *.sql|awk '{print "'\''source " $0 "'\''"}'部分输出结果:
其实可以看到这效果就类似于上面,使用for循环遍历目录再拼接soruce语句块的效果了。
接着最后是第三段使用了xargs命令,这里拆解两部分来看。先看后半部分mysql后面跟着一串参数,这一整串mysql -u gogs gogs -e命令是以用户gogs连接到gogs数据库,并执行一行命令的意思,但是可以看到-e后面缺少了本来应该有的sql命令参数。其实这就是第三段作用,也就是通过xargs命令,动态把第二段输出的每一行source语句库拼接到mysql -u gogs gogs -e后面,达到导入每个表数据的目的。看前半部分xargs -L 1 -t,-L 1作用是处理第二段的多行输出,把每行输出作为参数输入到mysql -e后面并执行,不然会把第二段的所有标准输出,当成参数拼接到mysql -u gogs gogs -e后面,这语法就错了。接着-t是方便查看最终每次执行的命令是什么样的。最后啰嗦了这么多看看输出结果:
这里已经能看到正在批量执行sql文件,之所以有报错是因为之前导入过一份数据,导致主键重复了。反正虽然走了很多弯路,但是总算是完成想要的效果。
本来也不是多么复杂的命令,可能对于实际业务而言,也不是很实用的命令,但是这毕竟也是提供了一种方法思路嘛,也许就有些特殊情况用得着,所以我希望分享出来可以帮到遇到类似问题的朋友。
最后非常感谢能看到最后的读者,如果我的思路能帮你解决到业务问题的话,就给我点个赞吧,你的一个赞可能就是我写(水)下一篇博文的动力。哈哈,说真的,原创不易,感谢支持,下篇博文再见。