0

我认为我有一个足够简单的问题,我最近运行了一个脚本,该脚本从数组中每个元素的字符串中提取特定信息。我以前写过这个,它运行良好,但是当现在尝试它的非常简单的版本时,它不会只提供相同的响应未初始化值参数的数据!由于我以前的代码有效,我感到非常沮丧。我显然在做一些愚蠢的事情,并希望得到一些帮助!

#!/usr/bin/env perl

use strict;
use warnings;


my@histone;
my$line;
my$idea;
my$file="demo_site.txt";

open(IN, "<$file")||die"\ncannot be opend\n";

@histone=<IN>;
print @histone;

foreach $line(@histone)
       {
           $line=~ m/([a-zA-Z0-9]+)\t[0-9]+\t[0-9]+\t/;

           print$1."\n";
           print$2."\n";
           print$3."\n";

       }

infile "demo_site.txt" 采用制表符分隔的 .txt 文件格式:

chr9        1234       5678     .     200      .      14.0      -1

该文件有多个如上所述的行,我希望提取前三项数据,因此输出如下所示。

chr9
1234
5678

干杯!

4

5 回答 5

3

你真的不需要正则表达式,因为它是制表符分隔的。

foreach $line(@histone)
       {
           @line_data = split(/\t/,$line)

           print $line_data[0]."\n";
           print $line_data[1]."\n";
           print $line_data[2]."\n";

       }

编辑:
如果要将值分配给特定的命名变量,请将其分配到临时数组中。

($varA, $varB, $varC .... ) = split(/\t/,$line)
于 2013-03-20T14:15:37.260 回答
2

这里的实际问题是您正在尝试打印 , 和 的值$1$2但是$3您的正则表达式中只有一组捕获括号,因此只能$1获取一个值。$2并且$3将保持未定义,因此当您尝试打印它们时会给您该错误。

解决方案是再添加两组捕获括号。我希望你想要这样的东西:

$line=~ m/([a-zA-Z0-9]+)\t([0-9]+)\t([0-9]+)\t/;
于 2013-03-20T14:55:44.947 回答
1

让我们假设,这file.txt有你想要的:(file.txt eq demo_site.txt

chr9        1234       5678     .     200      .      14.0      -1

你可以使用简单的东西:

perl -ane '$" = "\n"; print "@F[0..2]"' file.txt 1>output.txt

Perl 中的单行代码非常强大。而且您不需要为简单的任务编写脚本;)

有时只需打开终端;)

PS:

这不是很好的单线,我知道,但它做它必须做的事情。

于 2013-03-20T14:30:03.523 回答
0

如果我可以自我推销,您可以使用Tie::Array::CSV将文件作为 Perl arrayrefs 数组提供直接读写访问权限。

use strict;
use warnings;
use Tie::Array::CSV;
tie my @file, 'Tie::Array::CSV', 'demo_site.txt', sep_char => "\t";

print $file[0][0]; # first line before first tab
$file[2][1] = 10; # set the third line between the first and second tabs
于 2013-03-20T14:55:11.940 回答
0

$line=~ m/([a-zA-Z0-9]+)\t[0-9]+\t[0-9]+\t/)

首先,parens 是不平衡的。

其次,我还没有检查过这个,但你不需要为每次捕获设置一组括号吗?

第三,正如 misplacedme 所说, split() 绝对是要走的路。;)

于 2013-03-20T14:33:41.530 回答