Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用perl将文本文件转换为csv_Perl_Csv - Fatal编程技术网

使用perl将文本文件转换为csv

使用perl将文本文件转换为csv,perl,csv,Perl,Csv,我有一个长文本文件,我想在电子表格中转换它。它由Id、名称、长度和序列组成。每一个新的蛋白质都以(>)符号开始,顺序是Id、名称长度和新行上的序列 范例 1>LPT_ECOLI,190-255(顺时针),Thr操纵子先导肽 Kristitttitgngag 2>AK1H_ECOLI,337-2799(顺时针),双功能天冬氨酸激酶/高丝氨酸脱氢酶I MrVlkfggtsvanaerflvarvadilesnarqgqvatvlsap 输出 这张桌子是 Id长度名称序列 LPT_ECOLI 90-

我有一个长文本文件,我想在电子表格中转换它。它由Id、名称、长度和序列组成。每一个新的蛋白质都以(>)符号开始,顺序是Id、名称长度和新行上的序列

范例

1>LPT_ECOLI,190-255(顺时针),Thr操纵子先导肽
Kristitttitgngag
2>AK1H_ECOLI,337-2799(顺时针),双功能天冬氨酸激酶/高丝氨酸脱氢酶I
MrVlkfggtsvanaerflvarvadilesnarqgqvatvlsap
输出

这张桌子是

Id长度名称序列
LPT_ECOLI 90-255(Clockwisw)Thr操纵子激光肽Kristittt

带有一个有点笨拙的
sed
脚本:

sed -nE '/^[0-9]+[ \t]+>/ { s/^[0-9]+[ \t]+>[ \t]+//; h; n; x; G; s/\n/,/; s/[ \t]*,[ \t]*/,/g; p }'
输出:

LPT_ECOLI,190-255 (Clockwise),Thr operon leader peptide,KRISTTITTTITITTGNGAG
AK1H_ECOLI,337-2799 (Clockwise),Bifunctional aspartokinase/homoserine dehydrogenase I,MRVLKFGGTSVANAERFLRVADILESNARQGQVATVLSAP
LPT_ECOLI,190-255 (Clockwise),Thr operon leader peptide,KRISTTITTTITITTGNGAG
AK1H_ECOLI,337-2799 (Clockwise),Bifunctional aspartokinase/homoserine dehydrogenase I,MRVLKFGGTSVANAERFLRVADILESNARQGQVATVLSAP
您可以将其作为CSV导入电子表格

编辑:如果您坚持,Perl也是一样的:

perl -lpe 'chomp($_ .= "," . <>) if (s/^\d+\s*>\s*//o); s/\s*,\s*/,/g'
perl-lpe'chomp($\.=”,“)if(s/^\d+\s*>\s*//o);s/\s*,\s*/,/g'
在Perl中:

#!/usr/bin/perl
use strict; use warnings;
open(my $fh, "<", "foo.data") || die;
my $last_was_rec_start = 0;
my ($id, $len, $name);
foreach (my $lineno=1; my $line = <$fh>; $lineno++ ) {
    chomp($line);
    if ($last_was_rec_start) {
        # Add validation that line matches protein sequence?
        print "${id},${len},${name}',$line\n";
        $last_was_rec_start = 0;
        next;
    }
    my @fields = split(/,\s+/, $line);
    unless (scalar(@fields) == 3) {
        print STDERR "Malformed line ${lineno}; expecting 3 comma-delimited fields:\n${line}\n";
        next;
    };
    $len = $fields[1];
    $name = $fields[2];
    unless ($fields[0] =~ /\d+ > (.*)/) {
        print STDERR "Malformed line ${lineno}; expecting number >\n${line}\n";
        next;
    }
    $last_was_rec_start = 1;
    $id = $1;
}
基本上,代码从读取逗号或“,”上的行开始。找到的第一个字段子匹配删除编号>。在我们找到一条线匹配之后 后面的行作为序列行


但是,您可能还想看看。它可能会写入CSV文件,如果您的输入采用某种标准格式,它也可能能够读取该文件。

如果您的
ID
是唯一的,则可以执行您想要的操作:

my ($id, $length, $name, $sequence);
my %data;
while(<DATA>){
    chomp;
    my @split = split(/,/); 
    ($id, $length, $name) = @split[0..2] if /^\d+/;
    $id =~ s/^\d+\s>\s//;
    $data{$id} = [$name, $length, $_] if /^[A-Z]/;  
}


open my $out, '>', 'out.csv' or die $!;
print $out "Id,Length,Name,Sequence\n";

foreach my $id (sort keys %data){
    ($length, $name, $sequence) = @{$data{$id}};
    print $out "$id,$length,$name,$sequence\n";

}

__DATA__
1 > LPT_ECOLI, 190-255 (Clockwise), Thr operon leader peptide 
KRISTTITTTITITTGNGAG
2 > AK1H_ECOLI, 337-2799 (Clockwise), Bifunctional aspartokinase/homoserine dehydrogenase I
MRVLKFGGTSVANAERFLRVADILESNARQGQVATVLSAP
my($id,$length,$name,$sequence);
我的%数据;
while(){
咀嚼;
我的@split=split(/,/);
($id,$length,$name)=@split[0..2]if/^\d+/;
$id=~s/^\d+\s>\s/;
$data{$id}=[$name,$length,$\]if/^[A-Z]/;
}
打开我的$out,“>”、“out.csv”或die$!;
打印$out“Id、长度、名称、序列\n”;
foreach my$id(排序键%data){
($length,$name,$sequence)=@{$data{$id};
打印$out“$id,$length,$name,$sequence\n”;
}
__资料__
1>LPT_ECOLI,190-255(顺时针),Thr操纵子先导肽
Kristitttitgngag
2>AK1H_ECOLI,337-2799(顺时针),双功能天冬氨酸激酶/高丝氨酸脱氢酶I
MrVlkfggtsvanaerflvarvadilesnarqgqvatvlsap

这是通过在
上拆分数据并构建数组散列来实现的,使用id作为键,其他信息作为值。然后可以将其打印到
.csv
文件中

请在下面找到示例代码-在工作中,将
替换为
,并将其作为
脚本输出文件执行

use strict; use warnings;

# print CSV header line
print "N, Id, Length, Name, Sequence\n";

my($line1,$line2);
while( defined($line1=<DATA>) and defined($line2=<DATA>)) {
  # put two input lines slurped above into $_
  local $_ = $line1 . $line2;

  my ($N, $Id, $Length, $Name, $Sequence ) = m{
    ^(\d{1,6}) # $N - record numer (?)
    \x20>\x20
    ([A-Z1-9_]{1,128}?) # $Id
    \x20*,\x20*
    ([- ()0-9A-Za-z]{1,128}?) # Length
    \x20*,\x20*
    ([^,\"\'\n\r]{1,256}?) # $Name
    # the quotes (\"\') are escaped/backslashed to make SO syntax coloring work
    \x20*\r?\n
    ([A-Z]{1,4096}?) # $Sequence
    \r?\n
  }sox or die "wrong line format (line $.):\n $_";
  printf "%d, %s, %s, %s, %s\n", $N, $Id, $Length, $Name, $Sequence;
}
die if defined($line1); # incoplete set of input lines;
__DATA__
1 > LPT_ECOLI, 190-255 (Clockwise), Thr operon leader peptide
KRISTTITTTITITTGNGAG
2 > AK1H_ECOLI, 337-2799 (Clockwise), Bifunctional aspartokinase/homoserine dehydrogenase I
MRVLKFGGTSVANAERFLRVADILESNARQGQVATVLSAP
使用严格;使用警告;
#打印CSV标题行
打印“N,Id,长度,名称,序列\N”;
我的($line1,$line2);
while(已定义($line1=)和已定义($line2=)){
#将上面的两条输入线插入$_
本地$\u=$line1.$line2;
我的($N,$Id,$Length,$Name,$Sequence)=m{
^(\d{1,6})#$N-记录数字(?)
\x20>\x20
([A-Z1-9}{1128}?#$Id)
\x20*,\x20*
([-()0-9A-Za-z]{1128}?)长度
\x20*,\x20*
([^,\“\'\n\r]{1256}?)\$Name
#引号(\“\”)被转义/反斜杠以使SO语法着色有效
\x20*\r?\n
([A-Z]{14096}?)#$序列
\r?\n
}sox或die“错误的行格式(行$):\n$;
printf“%d、%s、%s、%s、%s\n”、$n、$Id、$Length、$Name、$Sequence;
}
如果定义了模具($line1)#不完整的输入线集合;
__资料__
1>LPT_ECOLI,190-255(顺时针),Thr操纵子先导肽
Kristitttitgngag
2>AK1H_ECOLI,337-2799(顺时针),双功能天冬氨酸激酶/高丝氨酸脱氢酶I
MrVlkfggtsvanaerflvarvadilesnarqgqvatvlsap
这里是另一个选项:

use strict;
use warnings;

while ( my $lines = <DATA> . <DATA> ) {
    print join (',', ( split />\s+|,\s+|\n/, $lines )[ 1 .. 4 ]), "\n";
}

__DATA__
1 > LPT_ECOLI, 190-255 (Clockwise), Thr operon leader peptide
KRISTTITTTITITTGNGAG
2 > AK1H_ECOLI, 337-2799 (Clockwise), Bifunctional aspartokinase/homoserine dehydrogenase I
MRVLKFGGTSVANAERFLRVADILESNARQGQVATVLSAP
while
循环从一次读取两行开始。
split
使用正则表达式在“>”或“\n”上拆分这些行,然后用逗号将
split
中的
元素1-4连接起来,并打印结果


希望这有帮助

那么问题是什么呢?到目前为止,您尝试了什么?失败的原因是什么?我不知道如何忽略每一行的“>”,还有一个问题是,每一个蛋白质都包含新行上的序列,因此如何为其编写代码?您的输出不是CSV。应该有一些分隔符分隔字段,比如逗号。我想把它保存在电子表格中。Like Id将只保存在Id列中。所有这些人都在编写免费代码,为什么还没有人使用呢?感谢rocky,但它的输出与输入格式相同,而不是以表格形式或列表形式。是的,输入文件有标准格式。我想你们不明白什么是CSV。好的,是否可以仅以txt格式创建表?“仅以txt格式”非常模糊。您将如何确定字段以这种“仅txt格式”结尾的位置?正如lcd047所写,您可以将其导入电子表格程序。请编辑您的问题以澄清您的意思。如果这是一种标准格式,它是否是BIoPerl理解的格式之一?另外,您是否能够或愿意在编码方面付出任何努力?@fugu-是的,通过连接数据文件句柄中的两次读取。不知道为什么会投反对票,但没有明确指出ID是唯一的要求,也没有感觉需要。如果数据量很大,那么保持散列会让事情变慢。也就是说,问题域和需求也不清楚。所以这可能很好,就像fugu的解决方案一样,我不能确定为什么会投反对票,但需要一个Perl解决方案。(如果你对这一点有异议,我同意,我不知道这有什么关系;这一部分是不合理的。)同时,紧凑型的解决方案对我来说有点神秘。我认为用英语描述sed正在做什么会很有帮助,这样如果它要求的一些假设没有得到满足,它可能会给出更改内容/位置的想法。我理解csv文件。看,我想在电子表格中转换文本文件。因为它的文件非常大。首先,我想删除所有这些“>”符号。然后第1列为ID由名称蛋白质组成(LPT_ECOLI下一行AK1H_ECOLI等),第2列为长度(190-255(顺时针)下一行337-2799(cl
LPT_ECOLI,190-255 (Clockwise),Thr operon leader peptide,KRISTTITTTITITTGNGAG
AK1H_ECOLI,337-2799 (Clockwise),Bifunctional aspartokinase/homoserine dehydrogenase I,MRVLKFGGTSVANAERFLRVADILESNARQGQVATVLSAP