【问题标题】:Adding a list to an array from different file format in perl在perl中从不同的文件格式将列表添加到数组中
【发布时间】:2017-07-14 10:17:46
【问题描述】:
open(IN_FILE, $id_file) or die "Cant open $id_file file";

while (my $id_list= <IN_FILE>) {
    chomp $id_list;

    if ($id_list =~ m/^#|^$/g) {
        next;
    }
        # This Works WELL
        # if the file comes in QIIME format 
    elsif($otus_tag){
        if ($id_list =~ m/^$otus_tag\t/g) {
            @list_id = split /\t/, $id_list;

        }

    }
        # This is the section that I want to FIX !!!!
        # if the format are in space, tab, semicolon, comma or in new line.

    elsif(!$otus_tag){
        if ($id_list =~ m/\s|\t|\,|\;/g) {
             @list_id = split /\s|\t|\,|\;/, $id_list;
        }


    } 
}

我有一个 perl 脚本的一部分,用于从 6 种不同格式的文件中提取 id 列表:

    Tab_delimited file:
    Y4.SW08.DCM.X4a_1386    Y4.SW08.DCM.X4a_1457    Y4.SW08.DCM.X4a_1590

    Tab_delimited_QIIME file:
    A100B1      Y4.SW08.DCM.X4a_1386    Y4.SW08.DCM.X4a_1457    Y4.SW08.DCM.X4a_1590

    Space_delimited file:
    Y4.SW08.DCM.X4a_1386 Y4.SW08.DCM.X4a_1457 Y4.SW08.DCM.X4a_1590

    Comma_delimited file:
    Y4.SW08.DCM.X4a_1386,Y4.SW08.DCM.X4a_1457,Y4.SW08.DCM.X4a_1590

    Semicolon_delimited file:
    Y4.SW08.DCM.X4a_1386;Y4.SW08.DCM.X4a_1457;Y4.SW08.DCM.X4a_1590

    List_delimited file:
    Y4.SW08.DCM.X4a_1386
    Y4.SW08.DCM.X4a_1457
    Y4.SW08.DCM.X4a_1590

目前,将 id 添加到数组中的代码效果很好,除了最后一种格式,列表分隔文件,我尝试在接下来的 2 行中添加一个 \n:

if ($id_list =~ m/\s|\t|\,|\;|\n/g)
@list_id = split /\s|\t|\,|\;|\n/, $id_list;

但当文件格式为列表时,它不会将id添加到数组中!!! ...... 任何想法 ???

非常感谢

【问题讨论】:

  • \s 包括\n
  • 永远不要使用if (/.../g)*。完全没有意义,并且行为与if (/.../) 略有不同。使用if (/.../)! (* - 除非您展开 while 循环。)
  • 我不知道你的问题是什么,但我怀疑你想知道为什么$id_list 不包含超过一行,即使你只放了一行?
  • @toolic 和 \t!
  • 问题是什么?

标签: arrays list perl newline qiime


【解决方案1】:

我认为您可以稍微简化一下您的代码,因为其中有一些冗余的正则表达式。你真的只需要在文件的每一行上运行一个split 函数,其字符类与我认为的可能性相匹配。我可能会简化为:

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

my $file = shift;

my @list_ids;
open(my $fh, "<", $file);
while (<$fh>) {
    next if m/^[\#\$]/;
    my @elems = split(/[\s+,;]/);
    # maybe another next regex / string comparison filter if $otus_tag?
    #next if $otus_tag and ! /.../;  ?
    #next unless $otus_tag eq $elems[0]; ?
    push(@list_ids, $_) for @elems;
}

print "$_\n" for @list_ids;

这在运行 6 种不同的文件类型后会输出以下内容:

$ for f in files/*file; do echo $f; ./parse_file.pl $f; echo; done
files/comma.file
Y4.SW08.DCM.X4a_1386
Y4.SW08.DCM.X4a_1457
Y4.SW08.DCM.X4a_1590

files/list.file
Y4.SW08.DCM.X4a_1386
Y4.SW08.DCM.X4a_1457
Y4.SW08.DCM.X4a_1590

files/semicolon.file
Y4.SW08.DCM.X4a_1386
Y4.SW08.DCM.X4a_1457
Y4.SW08.DCM.X4a_159

files/space.file
Y4.SW08.DCM.X4a_1386
Y4.SW08.DCM.X4a_1457
Y4.SW08.DCM.X4a_1590

files/tab.file
Y4.SW08.DCM.X4a_1386
Y4.SW08.DCM.X4a_1457
Y4.SW08.DCM.X4a_15

files/tab2.file
A100B1
Y4.SW08.DCM.X4a_1386
Y4.SW08.DCM.X4a_1457
Y4.SW08.DCM.X4a_159

我不知道 otus_tag 是什么,也不知道你想用这个变量做什么。但是我提出了一些想法来过滤它,如果这就是你想要做的。我表示为“tab2.file”的那个是我认为需要额外过滤的 otus_tag 文件,但是您的代码建议我们在输出中保留不同的字符串,所以我不知道您想在那里做什么。

当我运行你的脚本时,由于我们不知道 $otus_tag 是什么,所以在输入了一些虚拟变量之后,我得到了与我的脚本相同的答案。所以,我不完全确定你出了什么问题。也许你得到的一些示例输出和你真正想要的一些示例输出会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-17
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多