Perl:制表符分隔文件中的字符串格式

时间:2014-08-14 11:10:29

标签: perl matrix

我没有任何编程背景,所以如果你能解释为什么以及为什么你推荐的任何代码应该按原样编写,我将不胜感激。

我有2000多个样本的数据矩阵,需要在一列中操作以下格式。

我还想操纵其中一列的格式,以便更容易与我的其他矩阵合并。例如,一列称为样本号(列#16)。格式目前与ABCD-A1-A0SD-01A-11D-A10Y-09类似,但我想将其更改为格式化为以下ABCD-A1-A0SD-01A。这将允许我以正确的格式使它,以便我可以将其与另一个矩阵合并。我似乎无法找到有关如何继续此步骤的任何信息。

示例输入应如下所示:

ABCD-A1-A0SD-01A-11D-A10Y-09
ABCD-A1-A0SD-01A-11D-A10Y-09
ABCD-A1-A0SE-01A-11D-A10Y-09
ABCD-A1-A0SE-01A-11D-A10Y-09
ABCD-A1-A0SF-01A-11D-A10Y-09
ABCD-A1-A0SH-01A-11D-A10Y-09
ABCD-A1-A0SI-01A-11D-A10Y-09

我希望删除最后三个扩展程序。输出样本应如下所示:

ABCD-A1-A0SD-01A
ABCD-A1-A0SD-01A
ABCD-A1-A0SE-01A
ABCD-A1-A0SE-01A
ABCD-A1-A0SF-01A
ABCD-A1-A0SH-01A
ABCD-A1-A0SI-01A

最后,我要合并的矩阵具有不同的布局,换句话说,列和行的数量是不同的。当我解决将两个矩阵合并在一起的下一步时,这是一个问题。原始矩阵有大约52列和2,000多行,而合并矩阵只有15列和467行。

原始矩阵的每一行都有患者的突变信息。这意味着具有相同ID的同一患者可能会多次出现。第二个矩阵包含患者信息,因此没有患者在该矩阵中重复。合并矩阵时,我想确保每个患者突变(每行)与来自合并矩阵的相应信息相匹配。

我的示例代码:

#!/usr/bin/perl  
use strict;
use warnings;

my $file = 'sorted_samples_2.txt';

open(INFILE, $file) or die "Can't open file: $!\n";
open(my $outfile, '>', 'sorted_samples_changed.txt');

foreach my $line (<INFILE>) {
    print "The input line is $line\n";
    my @columns = split('\t', $line);

    ($columns[15]) = $columns[15]=~/:((\w\w\w\w-\w\d-\w|\w\w-\d\d\w)+)$/;

    printf  $outfile "@columns/n";
}

问题:代码删除标题并删除第16列中的字符串。

2 个答案:

答案 0 :(得分:0)

当您使用'use strict'时,您需要在声明中使用'my'来定义变量的范围。 在你的情况下,你应该在第一行使用我的@sort = sort {....} 你应该在某处定义一个数组引用$ t,以便在第二行中取消引用它。您没有在此代码中的任何位置声明@array,这就是您收到所有这些错误的原因。在你做之前,一定要明白你在做什么。

答案 1 :(得分:0)

有关您的代码的一些问题:

  • 干得好use strict;use warnings;。继续这样做

  • 无论何时进行文件或目录处理,都包括use autodie;

  • 始终使用词法文件句柄$infh而不是globs INFILE

  • 使用open的3参数形式。

  • 始终使用while循环逐行处理文件。使用for循环将整个文件加载到内存

  • 不要忘记chomp来自文件的输入。

  • 如果您想要标题的特殊逻辑,请使用行号变量$.

  • split的第一个参数是模式。使用/\t/。唯一的例外是' ',它具有特殊含义。目前,您通过使用单引号字符串来引入错误。

  • 使用正则表达式更改值时,请尝试关注您想要的内容而不是您想要的内容。在这种情况下,您似乎希望用短划线分隔4个组,然后截断其余组。专注于匹配这些群体。

  • 当您的意思是printf时,请不要使用print

以下内容适用于您的脚本:

#!/usr/bin/perl  
use strict;
use warnings;
use autodie;

my $infile = 'sorted_samples_2.txt';
my $outfile = 'sorted_samples_changed.txt';

open my $infh, '<', $infile;
open my $outfh, '>', $outfile;

while (my $line = <$infh>) {
    chomp $line;

    my @columns = split /\t/, $line;

    if ($. > 1) {
        $columns[15] =~ s/^(\w{4}-\w\d-\w{4}-\w{3}).*/$1/
            or warn "Unable to fix column at line $.";
    }

    print $outfh join("\t", @columns), "\n";
}