如何用sed命令将test.sql中char和varchar的数值翻倍?
问题:使用sed将SQL文件中char/varchar类型的长度数值翻倍
我有一个名为test.sql的文本文件,需要用sed命令把其中char和varchar类型后的数值乘以2。
原文件内容
create table test_table ( test01 char(40), test02 date, test03 varchar(80), test04 decimal(9,2) not null , test05 varchar(100), test06 serial not null );
期望修改后的内容
create table test_table ( test01 char(80), test02 date, test03 varchar(160), test04 decimal(9,2) not null , test05 varchar(200), test06 serial not null );
我尝试的命令及失败结果
命令1
sed -E 's:(char|varchar|nvarchar)\(([0-9]+)\):print \1\(\2 * 2\):g ' test.sql
执行结果:
[root@owen-test ~]# sed -E 's:(char|varchar|nvarchar)\(([0-9]+)\):print \1\(\2 * 2\):g ' test.sql create table test_table ( test01 print char(40 * 2), test02 date, test03 print varchar(80 * 2), test04 decimal(9,2) not null , test05 print varchar(100 * 2), test06 serial not null );
命令2
sed -E "s/(char|varchar)\(([0-9]+)\)/\1\(echo \"\\2*2\"|bc\)/g" test.sql
执行结果:
[root@owen-test ~]# sed -E "s/(char|varchar)\(([0-9]+)\)/\1\(echo \"\\2*2\"|bc\)/g" test.sql create table test_table ( test01 char(echo 40*2|bc), test02 date, test03 varchar(echo 80*2|bc), test04 decimal(9,2) not null , test05 varchar(echo 100*2|bc), test06 serial not null );
解决方案
sed本身不支持直接算术运算,需要借助shell的计算能力,以下两种方法可以解决问题:
方法1:sed结合bash算术扩展
sed -E 's/(char|varchar)\(([0-9]+)\)/echo "\1($((\2*2)))" /ge' test.sql
-E:启用扩展正则表达式,简化分组写法e选项:将替换后的内容作为shell命令执行,用执行结果替换原匹配文本$((\2*2)):bash算术扩展,把捕获到的长度数值直接乘以2
方法2:用awk实现(更直观)
如果允许使用awk,实现逻辑会更清晰:
awk '/(char|varchar)\([0-9]+\)/ { match($0, /(char|varchar)\(([0-9]+)\)/, arr) new_len = arr[2] * 2 sub(/(char|varchar)\([0-9]+\)/, arr[1]"("new_len")", $0) }1' test.sql
- 匹配包含
char(N)或varchar(N)的行 match函数捕获类型和长度数值到数组arr中- 计算新长度后,用
sub替换原内容 - 末尾的
1表示打印所有行
执行任意一种方法,都能得到你期望的修改结果。
内容的提问来源于stack exchange,提问作者Owen
相关产品推荐
相关产品推荐

