ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 用sed从mysqldump全备文件中取出某张表的表结构

用sed从mysqldump全备文件中取出某张表的表结构

原创 Linux操作系统 作者:czxin788 时间:2020-04-12 20:53:39 0 删除 编辑

  最近,看了一篇博客,写的是用sed取mysqldump文件里面的表结构内容,想了好长时间才明白是怎么回事,特此记录一下。

  原博文地址:  https://blog.csdn.net/u011156496/article/details/83308807

  假设原文件内容如下:

[root @demo -init ~]# cat  db1.sql
-- MySQL dump  10.13   Distrib  5.7 . 29 for  linux-glibc2. 12  (x86_64)
--
-- Host: localhost    Database: db1
-- ------------------------------------------------------
-- Server version    5.7 . 29 -log
 
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */ ;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */ ;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */ ;
/*!40101 SET NAMES utf8 */ ;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */ ;
/*!40103 SET TIME_ZONE='+00:00' */ ;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */ ;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */ ;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */ ;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */ ;
 
--
-- Table structure  for  table `t1`
--
 
DROP TABLE IF EXISTS `t1`;
/*!40101 SET @saved_cs_client     = @@character_set_client */ ;
/*!40101 SET character_set_client = utf8 */ ;
CREATE TABLE `t1` (
   `id`  int ( 11 ) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */ ;
 
--
-- Dumping data  for  table `t1`
--
 
LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */ ;
INSERT INTO `t1` VALUES ( 3306 );
/*!40000 ALTER TABLE `t1` ENABLE KEYS */ ;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */ ;
 
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */ ;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */ ;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */ ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */ ;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */ ;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */ ;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */ ;
 
-- Dump completed on  2020 - 04 - 12  15 : 43 : 52

  用sed取出其中表结构:

[root @demo -init ~]# sed -e  '/./{H;d}'  -e  'x;/CREATE TABLE `t1`/!d'   db1.sql
DROP TABLE IF EXISTS `t1`;
/*!40101 SET @saved_cs_client     = @@character_set_client */ ;
/*!40101 SET character_set_client = utf8 */ ;
CREATE TABLE `t1` (
   `id`  int ( 11 ) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */ ;

   这个取的很不错,把create table t1的sql语句完整的取到了。它是怎么做到的呢。

   首先,先解释一下sed的几个选项。

  • H命令是将当前模式空间中的内容追加至保持空间
  •  d命令是删除当前模式空间内容(不再传到标准输出), 并放弃之后的命令,读取新内容重新执行sed  (标红的很重要)
  •  x:命令把模式空间中的内容与保持空间中的内容进行互换
  • -e选项是执行多个处理动作,等效于;

    有了上面的了解,就可以解释下面这行命令了。

sed -e '/./{H;d}' -e 'x;/CREATE TABLE `t1`/!d'  db1.sql

  1. /./的意思是正则匹配,.是指任意单个字符,那么这个在这里面的意思就是匹配非空行,即有内容的行
  2. {}这个是命令的集合
  3. 因为sed是逐行处理文本的,一开始把第一行内容即-- MySQL dump 10.13 ....放在模式空间中,然后用H命令把-- MySQL dump 10.13 ...追加保持空间中,保持空间(默认存放个\n)存的内容就变成了\n-- MySQL dump 10.13 ...,接下来执行d命令,把模式空间中的内容-- MySQL dump 10.13 ...删掉,并不再执行后面 -e 'x;/CREATE TABLE `t1`/!d' 的命令
  4. 读取第二行内容即--放入模式空间中,然后执行命令H,把模式空间中的--追加到保持空间中,这时保持空间的内容就变成了\n-- MySQL dump 10.13 ..\n.--,然后执行命令d把模式空间中的内容--清除掉
  5. 然后一直重复上的步骤,直到第六行,是个空行,不符合/./这个正则表达式,所以第一个-e后的命令不执行,但是第二个-e后面的命令 'x;/CREATE TABLE `t1`/!d' 开始执行。先执行x命令,它的意思是要把模式空间中的的内容与保持空爱你中的内容进行互换,那也就是把模式空间的空内容和保持空间中的\n-- MySQL dump 10.13 ...\n–\n–Table structure.....交换,这样模式空间就有内容了,模式空间的内容执行/CREATE TABLE `t1`/!d命令,因为此时模式空间里面的内容不符合正则表达式/CREATE TABLE `t1`/,所以就要把模式空间中的内容用d命令清除掉;
  6. 于是继续执行,直到遇到create table `t1` 那组( db1.sql每组内容是用空行隔开的),sed就会把保持空间create table t1上下文的内容完整的输出到屏幕上

     其实,sed这串命令里的关键在d命令,它是 删除当前模式空间内容(不再传到标准输出), 并放弃之后的命令,读取新内容重新执行sed, 我读完这句话后,才终于想明白了这串sed命令是怎么取到create table t1上下文结果的了。

    不知道我描述清楚了吗。



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28916011/viewspace-2685707/,如需转载,请注明出处,否则将追究法律责任。

全部评论

注册时间:2014-06-03

  • 博文量
    205
  • 访问量
    657148