有一个 sql 转储文件,我需要根据它显示的模式进行修改。模式如下:
/*!50001 CREATE ALGORITHM=UNDEFINED */
/ *!50013 DEFINER='test'@'%' SQL SECURITY DEFINER */
/ *!50001 VIEW 'SOME DATA' AS select 'SOME DATA'.'SOME DATA' AS '一些数据','一些数据'.'一些数据'作为'一些数据'...
/ *!50001 SET character_set_client = @saved_cs_client */;
/ *!50001 SET character_set_results = @saved_cs_results */;
/ *!50001 SET collation_connection = @saved_col_connection */;
/*!40103 设置TIME_ZONE=@OLD_TIME_ZONE */;
对于每个模式,我想使用sed
或awk
/或两者来修改它:
/*!50001 CREATE VIEW 'SOME DATA' AS 选择 'SOME DATA'.'SOME DATA' AS 'SOME DATA','SOME DATA'.'SOME DATA' AS 'SOME DATA','SOME DATA'....
/ *!50001 SET character_set_client = @saved_cs_client */;
/ *!50001 SET character_set_results = @saved_cs_results */;
/ *!50001 SET collation_connection = @saved_col_connection */;
/*!40103 设置TIME_ZONE=@OLD_TIME_ZONE */;
总而言之,我想删除 CREATE 和 VIEW 之间的所有内容。我尝试了以下命令但它不起作用:
sed 's/50001 CREATE.*VIEW//' dumpsqlfile.sql
sed "/50001 CREATE/,/VIEW/d" dumpsqlfile.sql
答案1
如果
CREATE
位于该行中,则删除其后面的所有内容并将生成的行保存在 中saved
。如果
saved
为空,则打印当前行如果
saved
设置并且该行包含VIEW
,则删除 之前的所有内容VIEW
,打印前saved
一行,后跟当前修改的行,并saved
再次清空。
/CREATE/{sub(/CREATE.*/,"CREATE");saved=$0}
!saved
saved&&/VIEW/{
sub(/.*VIEW/,"VIEW")
print saved " " $0
saved=""
}
将其保存为 ascript.awk
并使用 运行它awk -f script.awk dumpsqlfile.sql
。输出:
/*!50001 CREATE VIEW 'SOME DATA' AS select 'SOME DATA'.'SOME DATA' AS 'SOME DATA','SOME DATA'.'SOME DATA' AS 'SOME DATA'...
/ *!50001 SET character_set_client = @saved_cs_client */;
/ *!50001 SET character_set_results = @saved_cs_results */;
/ *!50001 SET collation_connection = @saved_col_connection */;
/ *!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
sed 's/50001 CREATE.*VIEW//' dumpsqlfile.sql
不起作用因为 sed 是一个面向行的工具。一旦到达换行符,它将停止寻找模式。和
sed "/50001 CREATE/,/VIEW/d" dumpsqlfile.sql
还不起作用因为它开始删除匹配的行之间的每一行,50001 CREATE
直到匹配的行VIEW
,包括边界线。