簡體   English   中英

大文件上的多行正則表達式匹配字符串替換

[英]multiline regex match string replacement on large file

我有一個很大的mysqldump(4個以上的演出),並且我們有一個受此錯誤困擾的存檔類型表。最終結果是我需要將AUTO_INCREMENT計數器重置為零。 確實設法進行了替換,但是這很丑陋,涉及將文件分割成較小的塊,然后grepping查找表,查找要更改的數字,然后在原始文件上使用sed替換僅匹配項自動遞增。 就像我說的那樣,太可怕了,但是確實有效。

所以-我試圖破譯多行sed,但沒有走得太遠。 我想做的就是查找我感興趣的表名,然后從該點開始查找下一個AUTO_INCREMENT= ,然后匹配其中的數字並將其設為零。 表格如下:(假設在此之前和之后都有大量數據)

DROP TABLE IF EXISTS `archive_exported_problems`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `archive_exported_problems` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `export_id` int(11) DEFAULT NULL,
  `problem_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=ARCHIVE AUTO_INCREMENT=478 DEFAULT CHARSET=latin1;

我想要做的是(自動)掃描文件,直到匹配為止

(?:CREATE TABLE `archive_exported_problems).*?AUTO_INCREMENT=(\d+)

(似乎起作用的正則表達式),然后將捕獲組替換為0

我認為這是可能的-非常感謝您的幫助!

如果perl是一個選項,那么在perl使用DOTALL標志就更容易了,像這樣:

perl -00 -pe 
 's/(?s)(CREATE TABLE `archive_exported_problems`.*?AUTO_INCREMENT)=\d+/$1=0/' file.sql

DROP TABLE IF EXISTS `archive_exported_problems`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `archive_exported_problems` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `export_id` int(11) DEFAULT NULL,
      `problem_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
) ENGINE=ARCHIVE AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;

使用的選項有:

-00    # slurps whole file
(?s)   # enable DOTALL flag for regex

考慮一下:

$ sed -r '/CREATE TABLE `archive_exported_problems`/,/AUTO_INCREMENT=/ {s/(AUTO_INCREMENT)=[[:digit:]]+/\1=0/;}' file
DROP TABLE IF EXISTS `archive_exported_problems`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `archive_exported_problems` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `export_id` int(11) DEFAULT NULL,
  `problem_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=ARCHIVE AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;

對於Mac OSX(BSD),請嘗試:

$ sed -E -e '/CREATE TABLE `archive_exported_problems`/,/AUTO_INCREMENT=/ {s/(AUTO_INCREMENT)=[[:digit:]]+/\1=0/;}' file

這個怎么運作

  • /CREATE TABLE archive_exported_problems /, /AUTO_INCREMENT=/

    這將隨后的命令限制在以包含CREATE TABLE 'archive_exported_problems'的行開頭和以包含AUTO_INCREMENT=的行結尾的行上的范圍。

  • s/(AUTO_INCREMENT)=[[:digit:]]+/\\1=0/

    這將執行所需的替換。

局限性

此方法假定CREATE TABLE短語和AUTO_INCREMENT=短語永遠不會在同一行上。 如果那不是真的,我們需要做一些小的改動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM