我有一个大文件,其中包含将根据传递到的正则表达式替换的文本。正则表达式经过测试并且可以找到匹配的模式,但是当我使用它时sed
没有替换文本。请注意,我的环境是 Windows,内存为 16GB,文件大小约为 14GB。
sed -i "/,[\r\n]+ CONSTRAINT `[a-zA-Z0-9_]+` FOREIGN KEY \(`[a-zA-Z0-9_]+`\) REFERENCES `[a-zA-Z0-9_]+` \(`[a-zA-Z0-9_]+`\)/ s// /g" all_files_test.sql
(请注意,上面是cmd.exe
命令行,而不是 Unix shell)。
all_files_test.sql
文件:
DROP TABLE IF EXISTS `holdings_FLZWHX`;
;
;
CREATE TABLE `holdings_FLZWHX` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`DateAdded` datetime NOT NULL,
`FundId` int(11) NOT NULL,
`AssetId` int(11) NOT NULL,
`DayChangeEqt` decimal(18,2) DEFAULT NULL,
`PMinDayRet` decimal(18,2) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `holdings_FLZWHX_FundId` (`FundId`),
KEY `holdings_FLZWHX_AssetId` (`AssetId`),
KEY `holdings_FLZWHX_TypeId` (`TypeId`),
KEY `holdings_FLZWHX_TickerId` (`TickerId`),
KEY `holdings_FLZWHX_StyleId` (`StyleId`),
KEY `holdings_FLZWHX_SectorId` (`SectorId`),
KEY `holdings_FLZWHX_CountryId` (`CountryId`),
KEY `holdings_FLZWHX_CurrencyId` (`CurrencyId`),
CONSTRAINT `holdings_FLZWHX_ibfk_1` FOREIGN KEY (`FundId`) REFERENCES `target_funds` (`fundid`),
CONSTRAINT `holdings_FLZWHX_ibfk_2` FOREIGN KEY (`AssetId`) REFERENCES `asset` (`id`),
CONSTRAINT `holdings_FLZWHX_ibfk_3` FOREIGN KEY (`TypeId`) REFERENCES `type` (`id`),
CONSTRAINT `holdings_FLZWHX_ibfk_4` FOREIGN KEY (`TickerId`) REFERENCES `ticker` (`id`),
CONSTRAINT `holdings_FLZWHX_ibfk_5` FOREIGN KEY (`StyleId`) REFERENCES `style` (`id`),
CONSTRAINT `holdings_FLZWHX_ibfk_6` FOREIGN KEY (`SectorId`) REFERENCES `sector` (`id`),
CONSTRAINT `holdings_FLZWHX_ibfk_7` FOREIGN KEY (`CountryId`) REFERENCES `country` (`id`),
CONSTRAINT `holdings_FLZWHX_ibfk_8` FOREIGN KEY (`CurrencyId`) REFERENCES `currency` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4201 DEFAULT CHARSET=latin1;
;
我期待的结果:
DROP TABLE IF EXISTS `holdings_FLZWHX`;
;
;
CREATE TABLE `holdings_FLZWHX` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`DateAdded` datetime NOT NULL,
`FundId` int(11) NOT NULL,
`AssetId` int(11) NOT NULL,
`DayChangeEqt` decimal(18,2) DEFAULT NULL,
`PMinDayRet` decimal(18,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4201 DEFAULT CHARSET=latin1;
;
答案1
正则表达式经过测试是一个困难的陈述,因为不仅有基本和扩展的正则表达式,而且还有许多非标准风格,您正在使用其中一些。
您正在使用扩展正则表达式,您需要告诉您的
sed
with 选项-E
您正在模式中查找换行符(回车符、换行符),但
sed
确实逐行处理输入,因此除非您连接行,否则这永远不会匹配。但是,您似乎正在使用 GNUsed
,因此您可以-z
选择一次处理所有行。这对于示例有效,但对于大文件可能会失败。根据您的 shell,您可能需要使用单引号而不是双引号来保护脚本。
sed -zEi '/,[\r\n]+ 约束
[a-zA-Z0-9_]+
外键 ([a-zA-Z0-9_]+
) 引用[a-zA-Z0-9_]+
([a-zA-Z0-9_]+
)/ s// /g' all_files_test.sql
已经完成了您所期望的替换zsh
,也许也在您的cmd.exe
.尽管如此,行地址对于一个缓冲区中的所有行来说都是无意义的,所以
sed -zEi 's/,[\r\n]+ CONSTRAINT `[a-zA-Z0-9_]+` FOREIGN KEY \(`[a-zA-Z0-9_]+`\) REFERENCES `[a-zA-Z0-9_]+` \(`[a-zA-Z0-9_]+`\)/ /g' all_files_test.sql
更符合逻辑(结果保持不变)。最后,您没有解释您希望线条如何KEY `holding
消失。
但现在采用一种标准方法进行多行替换,该N;P;D
模式也适用于大文件:
sed -Ei 'N;/,*[\r\n]+ CONSTRAINT `[a-zA-Z0-9_]+` FOREIGN KEY \(`[a-zA-Z0-9_]+`\) REFERENCES `[a-zA-Z0-9_]+` \(`[a-zA-Z0-9_]+`\)/{s// /g;s/^/\n/;D;};P;D' all_files_test.sql
N
始终附加下一行,以便您的模式可以匹配。P
打印缓冲区的第一行并D
删除该第一行并重新开始其余的行。所以N;P;D
在模式空间中总是有一对线。
然而,如果我们确实替换了,我们只有一行,但想继续下一行,所以技巧是在模式的开头插入一个空行s/^/\n/
(sed
仅限 GNU!),以便被D
.