sed -e '/./{H;$!d;}' -e 'x;/CREA

2020-07-13  本文已影响0人  梵雲魔羅

学习MySQL的过程中遇到一条sed语句,作用是获取mysqldump 全备中某表的表结构

root@mysql ~:# sed -e '/./{H;$!d;}' -e 'x;/CREATE TABLE `salaries`/!d;q' /backups/full_2020-07-01.sql 

DROP TABLE IF EXISTS `salaries`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `salaries` (
  `emp_no` int NOT NULL,
  `salary` int NOT NULL,
  `from_date` date NOT NULL,
  `to_date` date NOT NULL,
  PRIMARY KEY (`emp_no`,`from_date`),
  CONSTRAINT `salaries_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

由于该条语句比较复杂。研究之后现给出本人的一些分析。

首先找到full.sql中CREATE TABLE `salaries` 前后的一些相关内容


root@mysql ~:# sed -n '/CREATE TABLE `salaries`/{p;=}' /backups/full_2020-07-01.sql

CREATE TABLE `salaries` (

219

该行位于第219行,现过滤其前后10行

root@mysql ~:# sed -n '210,230p'  /backups/full_2020-07-01.sql 
/*!80002 ANALYZE TABLE `employees` UPDATE HISTOGRAM ON `gender` WITH 100 BUCKETS */;

--
-- Table structure for table `salaries`
--

DROP TABLE IF EXISTS `salaries`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `salaries` (
  `emp_no` int NOT NULL,
  `salary` int NOT NULL,
  `from_date` date NOT NULL,
  `to_date` date NOT NULL,
  PRIMARY KEY (`emp_no`,`from_date`),
  CONSTRAINT `salaries_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `salaries`

分析该条语句的执行过程

sed -e '/./{H;$!d;}' -e 'x;/CREATE TABLE `salaries`/!d;q' /backups/full_2020-07-01.sql

首先sed -e /./{H;$!d;} 是需要匹配至少一个字符的行,然后将该行模式空间内容追加到保持空间,如果该行不是最后一行就删除模式空间的所有内容,接着读入下一个非空行。
仔细观察


DROP TABLE IF EXISTS `salaries`;
/*!40101 SET character_set_client = @saved_cs_client */;

前后都是以空行开始和结束的。
这时sed -e /./{H;$!d;}是匹配不到任何内容的,此时就会执行-e 'x;/CREATE TABLE `salaries`/!d;q' 语句
命令x是将保持空间的内容和模式空间互换,然后搜索关键字CREATE TABLE `salaries`,如果有关键字则两个空白行之间的内容都会保留,并且q退出sed语句。如果没有该关键字就会继续将下一个两空白行之间的内容H进保持空间,继续筛选。

总结:该语句实际上执行的就是从第一行开始读入,只要不是空行就H进保持空间,然后删除模式空间内容,继续读入下一行,如果遇到空行就会将模式空间的内容和保持空间的内容互换(x),然后筛选是否有我们需求的关键字,如果有我们需要的关键字就会通过(q)命令退出sed语句的执行,(因为该测试中只有employees库里有该表,具有唯一性,所以为了执行效率,找到该表的建表语句后就可以退出sed的执行)并且输出两空行之间的所有内容,如果没有就删除模式空间的全部内容,继续从该空行的下一行读入,以此循环。

上一篇下一篇

猜你喜欢

热点阅读