首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Perl解析sqlplus命令的输出?

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

Stack Overflow用户
提问于 2010-05-01 16:03:59
回答 3查看 1.7K关注 0票数 1

我有一个SQL文件,它会给出如下所示的输出:

代码语言:javascript
复制
10|1
10|2
10|3
11|2
11|4
.
.
.

我在一个Perl脚本中使用它,如下所示:

代码语言:javascript
复制
my @tmp_cycledef = `sqlplus -s $connstr \@DLCycleState.sql`;

在上面这条语句之后,由于@tmp_cycledef包含了SQL查询的所有输出,因此我希望将输出显示为:

代码语言:javascript
复制
10 1,2,3
11 2,4

我如何使用Perl做到这一点呢?

编辑:

我使用了以下代码:

代码语言:javascript
复制
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";
}

第一个print语句打印:

代码语言:javascript
复制
     2, 1
     2, 10
     2, 11
     2, 12
     3, 1
     3, 10
     3, 11

但出局永远是

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-05-01 16:19:17

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

代码语言:javascript
复制
# two must-have pragmas for perl development
use strict;    
use warnings;

Perl允许在使用变量时创建它们,$feldman = some_function()意味着您现在在本地名称空间中有了变量$feldman。但这样做的缺点是,您可能会输入$fldman,然后花很长时间找出为什么您认为是$feldman的东西没有价值。启用意味着如果遇到未声明的变量,代码将无法编译。您可以使用myour语句(或者在较早的Perl代码中使用use vars语句)来声明变量。

打开warnings只会在您未获得预期的值时发出警告。通常,警告往往过于敏感,但它们通常是用于开发代码的好东西。

代码语言:javascript
复制
my %hash; # the base object for the data

在这里,我声明了一个散列变量,我创造性地将其命名为%hash。符号(发音为"sijil") "%“告诉我们它是一个名称-值对的映射。这条my语句声明了变量,并使其对编译器来说是合法的。编译器会警告我%hsh的任何用法。

下一项是foreach循环(可以缩写为"for")。该循环将处理@tmp_cycledef中的行列表,并依次将每一行分配给$row。(我的$row)。

  1. 我们先对行执行chomp操作,删除该平台的行尾字符。
  2. 我们split '|‘字符上的行,创建一个由竖线分隔的字符串列表。
  3. ,然后我们将其存储在一个双层散列中。因为我们希望至少按第一个数字对它们进行分组。我们可以通过数组来完成此操作,并在散列中的位置创建一个数组,如下所示:push @{$hash{$key}}, $val,但我通常希望折叠重复项(并不是说您的示例中有任何重复项)。

这里:

代码语言:javascript
复制
foreach my $row ( @tmp_cycledef ) { 
    chomp $row; # removes the end-of-line character when present. 
    my ( $key, $val ) = split /\|/, $row; 
    # One of the best ways to merge lists is a presence-of idea
    # with the hash holding whether the value is present
    $hash{$key}{$val} = 1; 
}

一旦我们有了结构中的数据,我们需要迭代两个级别的散列keys。您希望以行分隔“顶级”数字,但希望将第二个数字连接在同一行上。因此,我们为每个第一个数字打印一行,并在同一行上join为每个数字存储的字符串列表,以逗号分隔。我们还对列表进行排序:{ $a <=> $b }只需获取关键字并对它们进行数字比较。所以你得到了一个数字顺序。

代码语言:javascript
复制
# 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";
}

正如我在评论中所说,默认情况下,sort会按字符顺序进行排序,因此您可以只说sort keys %hash

为了帮助你,你真的需要阅读其中的一些内容:

  • strictures
  • warnings
  • perldata
  • perlfunc --尤其是join
  • And data structure tutorial

myforeachchompsplitkeyssort

票数 1
EN

Stack Overflow用户

发布于 2010-05-01 16:05:16

使用hash of arrays将单个键的所有值收集在一起,然后打印出来:

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2010-05-01 18:34:06

如果您的输入是经过排序的(就像在提供的示例中一样),那么您实际上不需要为数组/散列的散列而烦恼。代码有点长,但不需要理解引用,并且对于大型数据集应该运行得更快:

代码语言:javascript
复制
#!/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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2749247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档