Perl:如何从文本文件中读取不同的值并放在数组中?

时间:2014-05-22 15:01:42

标签: oracle perl

...好友

(来自新手的问题,对不起,如果这个太详细了,但试图提供所有细节以避免任何混淆) 我正在编写一个脚本,该脚本从Oracle tnsentry文件中搜索所有SID条目,并使用不同的SID列表连接并查询数据库以获得结果。

Oracle tnsentry文件有很多重复项(SID = DB),所以尝试只使用不同的SID条目。

我可以通过提供数据库名称轻松连接到单个数据库,但我们有10个数据库,所以它有点棘手

  1. 读取tnsentry文件(tnsfile.txt)
  2. 搜索数据库别名(SID = db1,SID = db2等)
  3. 将每个db别名临时存储到数组
  4. 在$ dbConnect函数
  5. 中使用db连接的每个别名

    Mycode尝试:

    #!/usr/bin/perl
    use strict;
    
    my $uNamePass = "user/password";
    my @dbName;
    
    #Uses username password and dbName to connect databsae
    # e.g. user/password@db1
    
    foreach my $item(@dbName) {    
      $dbConnect = &connect($uNamePass."@".$dbName);
      &getRows;
    }
       exit($exitStatus);
    
    #------------
    sub readFile {
    
    my $fName  = "c:\tnsentry.txt";
    my $dbName;
    
    # open file
    if ( ! open (DAT, $fName) ) {
         ¨
      }
    
      # read file by each line
       while(<DAT>) {
          chomp;
    
      # if line begins with # sign, proceed to next
       next if /^\#/;
    
      # Next not able to figure out how to read each line and store distinct
      # DB name in an array to use for login in $dbConnect
      # I think I need to sepearte SID with /SID/ and search for string till it reaches ')'
    
    
    }
    

    示例文件(tnsfile.txt)

    DB1=
      (
      (ADDRESS = (PROTOCOL = TCP))
       ...
       ...
      (CONNECT_DATA = (SID = db1))
      )
    
    DB2=
      (
      (ADDRESS = (PROTOCOL = TCP))
       ...
       ...
      (CONNECT_DATA = (SID = db2))
      )
    
    DB3=
      (
      (ADDRESS = (PROTOCOL = TCP))
       ...
       ...
      (CONNECT_DATA = (SID = db3))
      )
    
    DB_ONE=
      (
      (ADDRESS = (PROTOCOL = TCP))
       ...
       ...
      (CONNECT_DATA = (SID = db1))
      )
    
    DB_TWO=
      (
      (ADDRESS = (PROTOCOL = TCP))
       ...
       ...
      (CONNECT_DATA = (SID = db2 ))
      )
    

2 个答案:

答案 0 :(得分:0)

看起来您只是希望能够处理您的tnsfile.txt文件以提取SID别名。

您只需要open该文件并复制此文件处理以获得所需的哈希值:

use strict;
use warnings;

my %sid;
my $name;

while (<DATA>) {
    $name = $1 if /^(\w+)=$/;
    $sid{$name} = $1 if /\(CONNECT_DATA\s*=\s*\(SID\s*=\s*(\w+)\s*\)/;
}

use Data::Dump;
dd \%sid;

__DATA__
DB1=
  (
  (ADDRESS = (PROTOCOL = TCP))
   ...
   ...
  (CONNECT_DATA = (SID = db1))
  )

DB2=
  (
  (ADDRESS = (PROTOCOL = TCP))
   ...
   ...
  (CONNECT_DATA = (SID = db2))
  )

DB3=
  (
  (ADDRESS = (PROTOCOL = TCP))
   ...
   ...
  (CONNECT_DATA = (SID = db3))
  )

DB_ONE=
  (
  (ADDRESS = (PROTOCOL = TCP))
   ...
   ...
  (CONNECT_DATA = (SID = db1))
  )

DB_TWO=
  (
  (ADDRESS = (PROTOCOL = TCP))
   ...
   ...
  (CONNECT_DATA = (SID = db2 ))
  )

输出:

{ DB1 => "db1", DB2 => "db2", DB3 => "db3", DB_ONE => "db1", DB_TWO => "db2" }

答案 1 :(得分:0)

虽然我不确定如果来自tnsnames.ora(或其他)的SID名称提取唯一列表确实是个好主意,因为不同主机上的不同Oracle数据库可能具有相同的SID,这里是什么你问过:

open(TNS,"tnsnames.ora")||die "ERROR: Can't open tnsnames.ora for read: $!";
while(<TNS>){$sids{$1}=0if/SID\s?=\s?(\w+)/}
print "$_\n" for(keys%sids);

或更长记谱法中的最后两行:

while (<TNS>)
{
   if (/SID\s?=\s?(\w+)/)
   {  $sids{$1} = 0 }
}

for (keys %sids)
{  print "$_\n" }