用sed從mysqldump全備檔案中取出某張表的表結構

czxin788發表於2020-04-12

  最近,看了一篇部落格,寫的是用sed取mysqldump檔案裡面的表結構內容,想了好長時間才明白是怎麼回事,特此記錄一下。

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

  假設原檔案內容如下:

[root @demo -init ~]# cat 
-- MySQL dump     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'  
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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章