學習MySQL的過程中遇到一條sed語句臂痕,作用是獲取mysqldump 全備中某表的表結(jié)構(gòu)
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 */;
由于該條語句比較復(fù)雜澡绩。研究之后現(xiàn)給出本人的一些分析事镣。
首先找到full.sql中CREATE TABLE `salaries` 前后的一些相關(guān)內(nèi)容
root@mysql ~:# sed -n '/CREATE TABLE `salaries`/{p;=}' /backups/full_2020-07-01.sql
CREATE TABLE `salaries` (
219
該行位于第219行,現(xiàn)過濾其前后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`
分析該條語句的執(zhí)行過程
sed -e '/./{H;$!d;}' -e 'x;/CREATE TABLE `salaries`/!d;q' /backups/full_2020-07-01.sql
首先sed -e /./{H;$!d;} 是需要匹配至少一個字符的行铐伴,然后將該行模式空間內(nèi)容追加到保持空間,如果該行不是最后一行就刪除模式空間的所有內(nèi)容玲献,接著讀入下一個非空行驱证。
仔細觀察
DROP TABLE IF EXISTS `salaries`;
/*!40101 SET character_set_client = @saved_cs_client */;
前后都是以空行開始和結(jié)束的。
這時sed -e /./{H;$!d;}是匹配不到任何內(nèi)容的获高,此時就會執(zhí)行-e 'x;/CREATE TABLE `salaries`/!d;q' 語句
命令x是將保持空間的內(nèi)容和模式空間互換摊趾,然后搜索關(guān)鍵字CREATE TABLE `salaries`,如果有關(guān)鍵字則兩個空白行之間的內(nèi)容都會保留肛炮,并且q退出sed語句粟害。如果沒有該關(guān)鍵字就會繼續(xù)將下一個兩空白行之間的內(nèi)容H進保持空間悲幅,繼續(xù)篩選留荔。
總結(jié):該語句實際上執(zhí)行的就是從第一行開始讀入碘勉,只要不是空行就H進保持空間倍宾,然后刪除模式空間內(nèi)容怔锌,繼續(xù)讀入下一行,如果遇到空行就會將模式空間的內(nèi)容和保持空間的內(nèi)容互換(x),然后篩選是否有我們需求的關(guān)鍵字彭羹,如果有我們需要的關(guān)鍵字就會通過(q)命令退出sed語句的執(zhí)行拓轻,(因為該測試中只有employees庫里有該表,具有唯一性枣氧,所以為了執(zhí)行效率,找到該表的建表語句后就可以退出sed的執(zhí)行)并且輸出兩空行之間的所有內(nèi)容种蝶,如果沒有就刪除模式空間的全部內(nèi)容螃征,繼續(xù)從該空行的下一行讀入盯滚,以此循環(huán)。