1

我希望将文件中的某些文本行拆分为一个对象,然后将这些对象添加到一个数组中,每个元素都是输入文件中的一行。从那里我需要调用此脚本的脚本才能通过它们的键引用对象中的标签(而不是将所有内容传递给打印命令并在调用脚本中重新组装。

我有第一部分工作和测试,但我不清楚如何在调用脚本中发送或尊重。我尝试打印出数组的每个元素,但由于它们是对象,一旦在调用程序中,它们就无法取消引用。

这是创建数组的文件的简化版本:

#!/usr/bin/perl

use strict;
use warnings;
use CLASS::DATATYPE;

my $foundheaders = 0;
my $array_elem = 0;
my @MY_ARRAY = ();

open FH, '<', "dummy.txt";
# open FH, '<', "$ARGV[0]";

while (my $line = <FH>) {
    # once you've found the headers, this will begin to kickoff
    if ($foundheaders == 1)
    {
        # get line elements and create a new DATATYPE object using the elements
        # matched to the header index
        my @lineArray = split("\t", $line);
        my $thisdata = new CLASS::DATATYPE();

        $thisdata->FIRSTVAL(@lineArray[$HEADERS::FIRST]);
        $thisdata->SECONDVAL(@lineArray[$HEADERS::SECOND]);

        print "$thisdata\n";

        # Add new DATATYPE to the array
        $MY_ARRAY[$array_elem] = $thisdata;
        $array_elem ++;
    };

    # Search for line with "#R" at the beginning.  This will contain the headers
    if ($line =~ m/#R/ ) {
        # strip the first # symbol from the headers
        my $subline = substr $line, 1;
        chomp($subline);

        # split the line into an array and index headers
        my @headers = split("\t", $subline);
        &assign_headers(\@headers);

        # check off foundheaders flag
        $foundheaders = 1;
    };
};
close FH;

# test output value
my $test = $MY_ARRAY[2]->SECONDVAL();
print "$test\n";

1;

sub assign_headers
{
    package HEADERS;
    my @array = @{$_[0]};
    my $iter = 0;

    # check each array loop against known headers and assign the array index to header
    foreach (@array)
    {
        if ($_ eq "ROW1")
        {
            our $FIRST = $iter;
        };

        if ($_ eq "ROW2")
        {
            our $SECOND = $iter;
        };
        $iter++;
    }
}

可以将 print 语句固定在原处,以确保至少按预期创建数据。

这是存储在 CLASS 文件夹中的 DATATYPE 包:

#!/usr/bin/perl

package CLASS::DATATYPE;

use strict;
use warnings;

sub new {
    my $self = {};
    $self->{FIRSTVAL} = undef;
    $self->{SECONDVAL} = undef;
    $self->{THIRDVAL} = undef;
    bless($self);
    return $self;
}

sub FIRSTVAL {
    my $self = shift;
    if (@_) { $self->{FIRSTVAL} = shift }
    return $self->{FIRSTVAL};
}

sub SECONDVAL {
    my $self = shift;
    if (@_) { $self->{SECONDVAL} = shift }
    return $self->{SECONDVAL};
}

1;

我使用了一个任意的虚拟文件,任何具有匹配标题行的东西都可以:

## blah blah blah
## blah blah blah
#ROWS   ROW1    ROW2    ROW3
1   fwewef  aewf    sfd8y9
2   gereer  few79   dfsui
3   svfsg789    aferw789    uifdgs
4   dfsgy   78fer   fds
5   78fgds  sdf78y  sfdgh

调用文件将类似于以下内容,传递输入文件并获取输出:

#!/usr/bin/perl

use strict;
use warnings;
use CLASS::DATATYPE;

my $file = "dummy.txt";

our @RESULTS = `/usr/bin/perl my_reader.pl $file`;

my $test = $RESULTS[2]->SECONDVAL();
print "$test\n";
4

1 回答 1

1

我能想到的解释我的意思的唯一方法是为你编写程序。

这个程序完全符合您的需要,我希望您能看到您编写了大量不必要的代码来做同样的事情。

我选择了你选择的类,但你所写的只是一个实现 Perl 哈希的类。

请遵守我使用的标识符的大小写。任何熟悉 Perl 的人都会习惯它们,并会感谢你。

我所做的唯一主要补充是将List::MoreUtils模块用于该firstidx功能。它返回符合给定测试的列表的第一个元素的索引。它不是核心模块,可能需要安装。如果您真的无法安装新模块,那么在程序中编写等效功能是一件简单的事情。如果您需要帮助,请回来。

注意我已经更新了代码以删除对这个模块的依赖,以防万一。

我已经让类从构造函数参数中获取初始化器,因此您可以在创建每个对象时分配值。此外,访问器返回任何更改之前的值,因为更改后的值不是很有用。

我希望您能看到,现在只需要read_maf处理其他文件格式的第二个子例程,并且不需要多个进程。

#!/usr/bin/perl

use strict;
use warnings;

use Class::DataType;

sub firstidx {
  my ($match, $list) = @_;
  for my $i (0 .. $#$list) {
    return $i if $list->[$i] eq $match;
  }
}

sub read_vcf {

  my ($filename) = @_;

  open my $fh, '<', $filename or die qq{Unable to open "$filename" for input: $!};

  my @columns;
  my @data;

  while (my $line = <$fh>) {
    chomp $line;
    if ( @columns ) {
        my @fields = split /\t/, $line;
        my $thisdata = Class::DataType->new(@fields[@columns]);
        push @data, $thisdata;
    }
    elsif ( $line =~ s/^#(?=R)// ) {
      my @headers = split /\t/, $line;
      @columns = map firstidx($_, \@headers), qw/ ROW1 ROW2 /;
    }
  }

  return \@data;
}

my $filename = 'dummy.txt';
my $results = read_vcf($filename);

my $test = $results->[2]->secondval;
print "$test\n";

Class::DataType和代码Class/DataType.pm

package Class::DataType;

use strict;
use warnings;

sub new {
  my $package = shift;
  $package = ref $package if ref $package;
  my $self = {};
  @$self{qw/ firstval secondval thirdval /} = @_;
  bless $self, $package;
}

sub firstval {
    my $self = shift;
    my $retval = $self->{firstval};
    $self->{firstval} = shift if @_;
    return $retval;
}

sub secondval {
    my $self = shift;
    my $retval = $self->{secondval};
    $self->{firstval} = shift if @_;
    return $retval;
}

sub thirdval {
    my $self = shift;
    my $retval = $self->{thirdval};
    $self->{firstval} = shift if @_;
    return $retval;
}

1;

输出

使用您提供的数据,这将打印

svfsg789
于 2013-02-23T00:30:38.190 回答