学习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的执行)并且输出两空行之间的所有内容,如果没有就删除模式空间的全部内容,继续从该空行的下一行读入,以此循环。
网友评论