2013-04-09 78 views
3

我有从一些其他文件中提取数据,形成一个大的(〜200MB)大批量SQL INSERT语句替换最后一个字符

INSERT INTO ... 
VALUES 
('a','b',1,2,3), 
('c','d',4,5,6), 

不幸的是,最后一行需要结束程序用分号代替逗号。有没有办法(最好在我的Perl程序中)只将,的最后一个字符变成;

事情我已经尝试:该文件已完成,关闭

1)后:

open(DAT,">>$output") || die("Cannot Open File"); 
seek(DAT, 2, SEEK_END); 
print DAT ";"; 
close(DAT); 

这只是把一个分号在最后。

2)从我的perl程序中调用`perl -p -i -e 's/,$/;/g' $output`;,但这是取代每个逗号。

3)打印最后一行时,以分号而不是逗号结束。但是这不起作用,因为我实际上并不知道这是直到写完这行为止的最后一行。

4)将整个文件复制到一个新的文件中,除了最后一个字符是;而不是,。然而这很慢,因此不理想。

+0

你反对CPAN模块? – squiguy 2013-04-09 17:59:50

+0

不幸的是。它运行在外部服务器上,具有相当严格的安装限制。不确定哪些模块可用。 不是最好的环境。 – AlexQueue 2013-04-09 18:01:52

回答

4

如果你知道了“”您要更换总是要在文件中(最后一个字节是一个‘\ n’)的倒数第二个字节,那么你可以试试这个:

my $fsize = -s $filename; 
# print $size."\n"; 
open($FILE, "+<", $filename) or die $!; 
seek $FILE, $size-2, SEEK_SET; 
print $FILE ";"; 
close $FILE; 
+0

工程很好,只不过它给出警告'参数“SEEK_SET”在app.pl第55行寻找不是数字​​。' 尽管它工作,但我很高兴。 – AlexQueue 2013-04-09 18:48:47

+0

@AlexQueue您可以用数字0代替SEEK_SET。 – imran 2013-04-09 18:59:33

+1

@AlexQueue或添加一个'use Fcntl;'来导入该定义。或者使用2(或SEEK_END)和否定位置,则不需要先捕获文件大小。 – sidyll 2013-04-09 19:00:10

1

您试图

perl -p -i -e 's/,$/;/g' 

将适用于文件中的每一行这种替换。只做一次,使用-0开关发出声音文件:

perl -0777 -pi -e 's/,$/;/' 

如果最后一个字符是一个逗号(带有可选尾随换行符),这将只匹配。如果你有空白或其他字符,它将不起作用。

+0

这在终端上运行良好,但不在我的Perl程序中运行。这不是一个大问题,但它意味着接受的答案更容易处理。 – AlexQueue 2013-04-09 18:49:46

0

您使用wron偏移量。 SEEK_END将(!)偏移量添加到END位置。所以使用“-2”作为偏移量。试试这个:

use strict; 
use warnings; 

open my $fh, "+<x.txt" or die; 
seek $fh, -2, 2; 
print $fh ";\n"; 
close $fh; 

还是有点更健谈:

use strict; 
use warnings; 
use Fcntl qw(SEEK_END); 

open my $fh, "+<x.txt" or die; 
seek $fh, -2, SEEK_END; 
print $fh ";\n"; 
close $fh; 
相关问题