匹配字符串与子串

时间:2016-08-08 18:26:50

标签: perl

我正在使用目录(Linux服务器)中的多个vcf文件以及包含样本名称和相应条形码的制表符分隔的密钥文件。

以下是文件的命名方式:

RA_4090_v1_RA_4090_RNA_v1.vcf
RA_4090_dup_v1_RA_4090_dup_RNA_v1.vcf
RA_565_v1.vcf
RA_565_dup_v1.vcf
RA_HCC-78-2.vcf

以下是密钥文件的内容:

Barcode ID      Sample Name
IonSelect-2     RA_4090
IonSelect-4     RA_565
IonSelect-6     RA_HCC-78-2
IonSelect-10    RA_4090_dup
IonSelect-12    RA_565_dup

我需要将正确的示例名称与每个.vcf文件相关联,然后重命名每个.vcf文件。

每个样本总有一个vcf文件。但是,有时样本名称以相同的子字符串开头,并且无法正确匹配它们,因为样本名称不是标准化的。

以下代码在样本名称不同时运行良好,但如果多个样本名称以相同的子字符串开头则会失败。我不知道如何考虑使用相同子字符串的多个样本名称。

请提出可行的建议。这是当前的代码:

#!/usr/bin/perl
use warnings;
use strict;
use File::Copy qw(move);

my $home="/data/";                                                     
my $bam_directory = $home."test_all_runs/".$ARGV[0];

my $matrix_key = $home."test_all_runs/".$ARGV[0]."/key.txt";

my @matrix_key = ();

open(TXT2, "$matrix_key") or die "Can't open '$matrix_key': $!";
        while (<TXT2>){  
                push (@matrix_key, $_);   
                }
close(TXT2);

my @ant_vcf = glob "$bam_directory/*.vcf";

for my $tsv_file (@ant_vcf){

        my $matrix_barcode_vcf = "";
        my $matrix_sample_vcf = "";

        foreach (@matrix_key){
                chomp($_);
                my @matrix_key = split ("\t", $_);##  
                if (index ($tsv_file,$matrix_key[1]) != -1) {
                  $matrix_barcode_vcf = $matrix_key[0]; print $matrix_key[0];
                  $matrix_sample_vcf = $matrix_key[1];
                  chomp $matrix_barcode_vcf;
                  chomp $matrix_sample_vcf;
                  #print $bam_directory."/".$matrix_sample_id."_".$matrix_barcode.".bam";
                  move $tsv_file, $bam_directory."/".$matrix_sample_vcf."_".$matrix_sample_vcf.".vcf";
                }       
        }

}

1 个答案:

答案 0 :(得分:1)

  

以下代码在样本名称不同时运行良好,但如果多个样本名称以相同的子字符串开头则会失败。我不知道如何考虑使用相同子字符串的多个样本名称。

解决问题的关键是排序&#39;样品名称&#39;名字长度 - 最长的。

例如,MATCHES RA_4090_dup应该在MATCHES RA_4090数组中的@matrix_key之前,因此它将首先尝试匹配较长的字符串。然后,在匹配之后,您停止搜索(我使用first模块中的List::Util,该模块是自5.08版以来属于核心perl的一部分。

#!/usr/bin/perl
use strict;
use warnings;
use List::Util 'first';

my @files = qw(
RA_4090_v1_RA_4090_RNA_v1.vcf
RA_4090_dup_v1_RA_4090_dup_RNA_v1.vcf
RA_565_v1.vcf
RA_565_dup_v1.vcf
RA_HCC-78-2.vcf
);

open my $key, '<', 'junk.txt' or die $!; # key file

<$key>; # throw away header line in key file (first line)

my @matrix_key = sort {length($b->[1]) <=> length($a->[1])} map [ split ],  <$key>;
close $key or die $!;

for my $tsv_file (@files) {
    if ( my $aref = first { index($tsv_file, $_->[1]) != -1 } @matrix_key ) {
        print "$tsv_file \t MATCHES $aref->[1]\n";
        print "\t$aref->[1]_$aref->[0]\n\n";    
    }
}

这产生了这个输出:

RA_4090_v1_RA_4090_RNA_v1.vcf    MATCHES RA_4090
        RA_4090_IonSelect-2

RA_4090_dup_v1_RA_4090_dup_RNA_v1.vcf    MATCHES RA_4090_dup
        RA_4090_dup_IonSelect-10

RA_565_v1.vcf    MATCHES RA_565
        RA_565_IonSelect-4

RA_565_dup_v1.vcf        MATCHES RA_565_dup
        RA_565_dup_IonSelect-12

RA_HCC-78-2.vcf          MATCHES RA_HCC-78-2
        RA_HCC-78-2_IonSelect-6