如何使用Perl解析sqlplus命令的输出?

如何使用Perl解析sqlplus命令的输出?,sql,perl,unix,Sql,Perl,Unix,我有一个SQL文件,它将为我提供如下输出: 10|1 10|2 10|3 11|2 11|4 . . . my @tmp_cycledef = `sqlplus -s $connstr \@DLCycleState.sql`; 我在Perl脚本中使用了它,如下所示: 10|1 10|2 10|3 11|2 11|4 . . . my @tmp_cycledef = `sqlplus -s $connstr \@DLCycleState.sql`; 在上述语句之后,由于@tmp\u cyc

我有一个SQL文件,它将为我提供如下输出:

10|1
10|2
10|3
11|2
11|4
.
.
.
my @tmp_cycledef = `sqlplus -s $connstr \@DLCycleState.sql`;
我在Perl脚本中使用了它,如下所示:

10|1
10|2
10|3
11|2
11|4
.
.
.
my @tmp_cycledef = `sqlplus -s $connstr \@DLCycleState.sql`;
在上述语句之后,由于
@tmp\u cycledef
具有SQL查询的所有输出, 我想将输出显示为:

10 1,2,3
11 2,4
如何使用Perl实现这一点

编辑:

我正在使用以下代码:

foreach  my $row (@tmp_cycledef)
{
        chomp $row;
        my ($cycle_code,$cycle_month)= split /\s*\|\s*/, $row;
        print "$cycle_code, $cycle_month\n";
        $hash{$cycle_code}{$cycle_month}=1
}

foreach my $num ( sort keys %hash )
{
        my $h = $hash{$num};
        print join(',',sort keys %$h),"\n";
}
fist print语句打印:

     2, 1
     2, 10
     2, 11
     2, 12
     3, 1
     3, 10
     3, 11
但问题总是无法解决

1,10,11,12
1,10,11,12
1,10,11,12
1,10,11,12
1,10,11,12
1,10,11,12
1,10,11,12
使用a将单个键的所有值收集在一起,然后打印出来:

init hash
for each line:
  parse into key|value
  append value to hash[key]

for each key in hash:  # you can sort it, if needed 
  print out key, list of values

实际上,这是在perl中实现的方法:

Perl允许在使用变量时创建变量,
$feldman=some_function()
意味着您现在在本地名称空间中有了变量
$feldman
。但不好的是,您可以键入
$fldman
,然后花很长时间找出您认为的
$feldman
没有价值的原因。启用此选项意味着您的代码在遇到未声明的变量时无法编译。您可以使用
my
our
语句(或在较旧的Perl代码中使用
use vars
语句)声明变量

启用该选项只会在您无法获得预期值时发出警告。警告通常过于敏感,但它们通常是开发代码的好方法

my %hash; # the base object for the data
在这里,我声明了一个哈希变量,我创造性地将其称为
%hash
。sigil(发音为“sijil”)“%”表示它是名称-值对的映射。此语句声明了该变量并使其对编译器合法。编译器将警告我使用
%hsh

下一项是一个循环(可以缩写为“for”)。循环将处理
@tmp\u cycledef
中的行列表,将每一行依次分配给
$row
(my
$row

  • 我们首先删除行,删除该平台的行尾字符
  • 我们在“|”字符上添加一行,创建一个由管道分隔的字符串列表
  • 然后我们将其存储在一个两层的散列中。因为我们希望至少按第一个数字对它们进行分组。我们可以按数组进行分组,并在散列中的位置创建一个数组,如下所示:
    push@{$hash{$key}},$val
    ,但我通常希望折叠重复项(不是因为您的示例中有任何重复项)
  • 在这里:

    一旦我们在结构中有了数据,我们就需要迭代这两个层次的散列。您想要分离“顶层”一行接一行的数字,但您希望第二个数字连接在同一行上。因此,我们为第一个数字打印一行,并为同一行上的每个数字存储字符串列表,以逗号分隔。我们还对列表进行排序:
    {$a$b}
    只取键并对它们进行数字比较。因此,您可以获得数字顺序

    # If they were alpha keys our sort routine, we would just likely say sort keys %hash
    foreach my $num ( sort { $a <=> $b } keys %hash ) { 
        my $h = $hash{$num};
        print "$num ", join( ',', sort { $a <=> $b } keys %$h ), "\n";
    }
    
    #如果它们是我们的排序例程中的alpha键,我们很可能会说sort key%hash
    foreach my$num(排序{$a$b}键%hash){
    my$h=$hash{$num};
    打印“$num”,连接(“,”,排序{$a$b}键%$h),“\n”;
    }
    
    正如我在评论中所说,默认情况下,按字符顺序排序,因此您可以只说
    排序键%hash

    为了帮助您,您确实需要阅读以下内容:

    • 尤其是
    如果对输入进行了排序(如提供的示例中所示),则实际上不需要对数组/哈希进行哈希处理。代码稍长,但不要求您理解引用,对于大型数据集,应该运行得更快:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my @tmp_cycledef = <DATA>;
    
    my $last_key;
    my @values;
    for (@tmp_cycledef) {
      chomp;
      my ($key, $val) = split '\|';
    
      # Seed $last_key with the first key value on the first pass
      $last_key = $key unless defined $last_key;
    
      # The key has changed, so it's time to print out the values associated
      # with the previous key, then reset everything for the new one
      if ($key != $last_key) { 
        print "$last_key " . join(',', @values) . "\n";
        $last_key = $key;
        @values = ();
      }
    
      # Add the current value to the list of values for this key
      push @values, $val;
    }
    
    # Don't forget to print out the final key when you're done!
    print "$last_key " . join(',', @values) . "\n";
    
    __DATA__
    10|1
    10|2
    10|3
    11|2
    11|4
    
    !/usr/bin/perl
    严格使用;
    使用警告;
    my@tmp_cycleedef=;
    我的$last_钥匙;
    我的价值观;
    对于(@tmp_cycledef){
    咀嚼;
    我的($key,$val)=拆分“\\”;
    #在第一次传递时使用第一个键值为$last_键设定种子
    $last_key=$key,除非定义了$last_key;
    #键已更改,因此是打印相关值的时候了
    #使用上一个键,然后重置新键的所有内容
    如果($key!=$last_key){
    打印“$last_key”.join(',',@values)。“\n”;
    $last_key=$key;
    @值=();
    }
    #将当前值添加到此键的值列表中
    推送@values,$val;
    }
    #完成后,别忘了打印出最后一把钥匙!
    打印“$last_key”.join(',',@values)。“\n”;
    __资料__
    10|1
    10|2
    10|3
    11|2
    11|4
    
    谢谢……因为我是perl新手。你能解释一下这是怎么回事吗?@benjamin button:我已经填了很多了。嗨,Axeman,我想告诉你,
    打印“$”,加入(',',排序{$a$b}键%$h)
    不起作用。
    “$”
    应该是
    “$num”
    @benjamin button:说得好。我没有把它从
    $版本转换成完整的版本。