如何用Sed/Awk删除最后一个INSERT INTO之后的所有行?
解决方法:删除最后一个INSERT INTO之后的所有行
这问题我日常处理SQL文件时经常碰到,用命令行工具就能轻松搞定,给你几个实用的方案:
方法1:用awk单步处理(推荐,适合大文件)
awk可以一次性遍历文件,记录最后一个INSERT INTO的行号,然后只输出到该行号的内容:
awk '{ # 只要当前行包含INSERT INTO,就更新最后保留的行号 if (/INSERT INTO/) { last_insert_line = NR } # 只输出行号小于等于最后保留行号的内容 if (NR <= last_insert_line) { print } }' 你的文件名.sql
用法说明
直接把上面的命令里的你的文件名.sql换成你实际的文件名就行,运行后会直接输出处理后的内容。如果要覆盖原文件,可以用:
awk '{...}' 你的文件名.sql > temp.sql && mv temp.sql 你的文件名.sql
(注意:覆盖前最好备份原文件!)
方法2:用grep+sed组合(直观易懂)
先找到最后一个INSERT INTO所在的行号,再用sed输出到该行号的内容:
# 第一步:获取最后一个INSERT INTO的行号 LAST_INSERT_LINE=$(grep -n "INSERT INTO" 你的文件名.sql | tail -n 1 | cut -d: -f1) # 第二步:输出1到该行号的所有内容 sed -n "1,${LAST_INSERT_LINE}p" 你的文件名.sql
用法说明
同样替换文件名即可,要是想直接修改原文件,同样可以重定向到临时文件再替换。
方法3:用sed单行命令
sed也可以通过模式匹配直接处理,把所有内容读到缓冲区后,只保留到最后一个INSERT INTO的部分:
sed 'H; ${x; s/\(.*INSERT INTO.*\)\n.*/\1/; p; d}' 你的文件名.sql
原理说明
H:把每一行追加到sed的保持缓冲区${x}:到最后一行时,把保持缓冲区的内容交换到模式空间s/\(.*INSERT INTO.*\)\n.*/\1/:匹配最后一个INSERT INTO之后的所有内容并删除p:输出处理后的内容
示例效果
假设你的原文件内容是:
INSERT INTO table (columns) values (1,x,b); INSERT INTO table (columns) values (2,y,c); INSERT INTO table (columns) values (3,w,d); INSERT INTO table (columns) values (4,z,e); -- Comment SELECT * FROM table; -- Comment SELECT * FROM table;
用上面任意一种方法处理后,输出结果都是前四行的INSERT INTO语句,后面的注释和SELECT语句都会被删除。
内容的提问来源于stack exchange,提问作者ganthdev
相关产品推荐
相关产品推荐

