Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 自动修改文本文件_Perl_Replace_Scripting_Automation_Text Processing - Fatal编程技术网

Perl 自动修改文本文件

Perl 自动修改文本文件,perl,replace,scripting,automation,text-processing,Perl,Replace,Scripting,Automation,Text Processing,这是我的问题:我有一个目录,其中包含来自Oracle即时客户端的一系列示例代码。它们中的每一个都演示了一个简单的数据库操作。我的目标是改变他们所有的连接顺序 他们有两种联系方式。要么是 EXEC SQL CONNECT :username IDENTIFIED BY :password; 或者他们会 EXEC SQL CONNECT :uid; 在第一种情况下,我们在程序的前面定义了变量 char *username = "scott"; char *password = "tiger";

这是我的问题:我有一个目录,其中包含来自Oracle即时客户端的一系列示例代码。它们中的每一个都演示了一个简单的数据库操作。我的目标是改变他们所有的连接顺序

他们有两种联系方式。要么是

EXEC SQL CONNECT :username IDENTIFIED BY :password;
或者他们会

EXEC SQL CONNECT :uid;
在第一种情况下,我们在程序的前面定义了变量

char *username = "scott";
char *password = "tiger";
每当我遇到使用此序列的程序时,我首先要更改密码,然后在上面两行下面添加一行,以获得以下结果

char *username = "scott";
char *password = "newPassword";
char *sqlHost = "hostid";
然后我需要将上面的连接顺序(我们在案例1中)更改为

如果我们是案例二,那么在程序的前面我们定义了变量

char *uid = "scott/tiger";
这种情况更容易处理:我所需要做的就是将定义更改为

char *uid = "scott/newPassword/hostid";
我可以保持连接顺序不变

我不是要求有人为我写这整件事,只是给我一些建议。我一直在阅读一些Perl文档以获得一些想法,但我不确定如何动态更改文件游标,以便可以在匹配的模式后直接插入一行。我也不完全确定如何用一个脚本来区分这两种情况(那么,假设我可以将模式编写为仅在其中一种情况下匹配,我可能也不必这样做)

我可以解决这个问题的另一种方法是使用第二种类型的序列将它们全部更改为连接。在这种情况下,我想我可以插入一个新行,根据需要声明一个
uid
,然后修改连接序列,使其始终采用第二种类型的形式。我还想删除前面的变量声明
username
password


非常感谢。

对于适合存储的文件:

  • 将文件“slurp”成数组
  • 循环遍历数组的行
    • 检查每行是否与$usernameRe匹配,如果匹配,则保存行号
    • 检查每行是否与$prefixRe匹配
      • 如果行与$caseOnePrefixRe匹配,请记下行号并将其标记为case1
      • 否则将其标记为案例2
      • 终止循环
  • 根据需要,使用保存的数组索引更新(现有)行
  • 循环遍历数组以将行写入输出
    • 根据保存的数组索引添加适当的额外行(如果需要)
  • 对于无法放入内存的文件,您必须对每个文件进行两次遍历,每次处理一行

    在这种情况下,简单的正则表达式就足够了:

    use strict ;
    use warnings ;
    use Test::More ;
    
    my $usernameStr = 'char *username = "scott"' ;
    my $usernameRe = qr/char\s\*username\s=/ ;
    like( $usernameStr, $usernameRe, "username RE works" ) ;
    
    my $caseOneStr = 'EXEC SQL CONNECT :username IDENTIFIED BY :password;' ;
    my $caseTwoStr = 'EXEC SQL CONNECT :uid;' ;
    my $prefixRe = qr/EXEC\sSQL\sCONNECT\s/ ;
    like( $caseOneStr, $prefixRe, "Prefix RE works for Case 1" ) ;   
    like( $caseTwoStr, $prefixRe, "Prefix RE works for Case 2" ) ;
    
    my $caseOnePrefixRe =  qr/EXEC\sSQL\sCONNECT\s:[[:alnum:]]+\sIDENTIFIED\sBY/ ;
    like ( $caseOneStr, $caseOnePrefixRe, "Case 1 prefix RE works for Case 1" ) ;    
    unlike ( $caseTwoStr, $caseOnePrefixRe, "Case 1 prefix RE rejects Case 2" ) ;
    
    如果文件可以保存在内存中,则执行以下操作将文件读入行数组:

    my $filename = 'foo' ;
    open my $fh, "<", $filename ;
    my @lines = <$fh> ;
    close $fh ;
    
    for ( my $i = 0; $i < scalar( @lines ); $i++ ) {
        # scan &/or update $lines[$i] in this iteration
    }
    
    my$filename='foo';
    打开我的$fh,”
    
    for ( my $i = 0; $i < scalar( @lines ); $i++ ) {
        # scan &/or update $lines[$i] in this iteration
    }