3

我有一个巨大的文本数据文件(~100MB),它是一堆数据文件的串联,带有各种标题信息,然后是一些数据列。这就是问题所在。我想在每个数据集之前从标题信息中提取一个特定的数字,然后将其附加到数据中的另一列(并将该数据写到不同的文件中)。

我想要的标题信息格式为:BGA 1

对于那个额外的数据列,我想要的是 BGA 之后的#。这将是一个介于 1 到 20000 之间的数字。我可以编写正则表达式来提取 BGA 一词,但我似乎无法弄清楚如何获得它后面的数字。

为了增加额外的乐趣,文本“BGA 1”在每个数据部分重复两次。

这是我到目前为止所拥有的,实际上不起作用......我希望它每次遇到 BGA 这个词时至少打印“BGA”,但它什么也没打印......任何帮助将不胜感激。

#!/usr/bin/perl
use strict;
use warnings;
my $file = 'alldata.txt';
open my $info, $file or die "Could not open $file: $!";
$_="";

while(my $line = <$info>){

    if ($line eq "/BGA/"){
    print <>,"\n";
        }
}
close $file;
4

3 回答 3

2
if ($line =~ /BGA\s(\d+)/){
  #your code
  print "BGA number $1 \n";
  #your code
}

$1变量将有你想要的数字

于 2013-08-22T21:23:15.093 回答
0

如果每行有多个 BGA,则需要允许正则表达式在每行匹配多次:

while (my $line = <$info>) {
  while ( $line =~ /BGA\s(\d+)/g ) {
    print "$1\n";
  }
}

这应该将所有 BGA 编号打印为一列。没有任何进一步的信息,很难更好地回答这个问题。

于 2013-08-22T22:00:25.100 回答
0

首先,100 MB 的文件并不大。不要那么失败主义。你甚至可以把它吸进内存:

让我们看一下代码中的几个关键位置:

while(my $line = <$info>) {
    if ($line eq "/BGA/") {

您的条件$line eq "/BGA/"测试该行是否由字符串组成"/BGA/"。但是,对于至少具有输入记录分隔符的行(即$/末尾的内容),这永远不会是真的,因为您没有这样chomp做。在任何情况下,您想要的是匹配包含"BGA"任何地方的行,并且执行此操作的正确 Perl 语法是

    if ($line =~ /BGA/) {

现在,一旦你解决了这个问题,你就会遇到以下语句的问题:

print <>,"\n";

你真正想要的是print $line;。列表上下文中的菱形运算符<>将尝试STDIN从命令行中指定为参数的任何文件或任何文件中啜饮。不是一个好主意。

其他人指出了如何匹配字符串"BGA"后跟一个数字。为了获得更好的答案,您将需要展示输入和预期输出的示例。

于 2013-08-22T23:06:34.227 回答