繁体   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