将行转换为列

5

我有一个文件,格式如下所示,我想将其转换为两列格式。

>00000_x1688514
TGCTTGGACTACATATGGTTGAGGGTTGTA
>00001_x238968
TGCTTGGACTACATATTGTTGAGGGTTGTA
...

期望输出结果为:

>00000_x1688514 TGCTTGGACTACATATGGTTGAGGGTTGTA
>00001_x238968 TGCTTGGACTACATATTGTTGAGGGTTGTA
...

我很感激您的帮助。谢谢。


2
什么问题?只需读取文件并为每两行输出1行。 - Chip
是我还是示例输入与期望输出相同? - Jon Clements
@JonClements -- 我认为>字符实际上在文件中。它们并不是实际标记行的开头。 - mgilson
@mgilson 你是对的,> 字符表示特定条目的标题行的开头。对我来说,它看起来像是 FASTA 文件格式。但我只是一个化学家,不太懂这个 ;) - Klaus-Dieter Warzecha
8个回答

7

我不知道你是否了解BioPerl模块,可以用于读写和其他基因功能。你的问题可以这样描述。

#!/usr/bin/perl
use strict;
use warnings;
use Bio::SeqIO;

my $file = 'o33.txt';
my $in  = Bio::SeqIO->new( -file   =>  $file,
                           -format => 'fasta');

while ( my $seq = $in->next_seq() ) {
    print $seq->id, "\t", $seq->seq, "\n";
}

__END__
00000_x1688514  TGCTTGGACTACATATGGTTGAGGGTTGTA
00001_x238968   TGCTTGGACTACATATTGTTGAGGGTTGTA

6

在Python中:

fd = open('filepath')
cols = izip(fd, fd)
with open('output_filepath') as outfile:
    for col in cols:
        outfile.write('\t'.join(col).replace('\n', '') +'\n')

期望的输出应该在 output_filepath 中。

1
这是一个非常聪明的izip使用方法(我从未想过用生成器与自身“压缩”以将其分成块)。 - mgilson
@mgilson:我希望这是我自己想出来的。我最初是在另一个SO帖子中读到的,但不幸的是我现在无法找到它。但当我读到它时,我的确有同样的感觉。 - inspectorG4dget
只是一点小问题:''.join(col).replace('\n', '\t') 可能更好的写法是:'\t'.join(col).replace('\n', '')。我认为这样更清晰,而且不会在行末添加额外的制表符。 - mgilson

2

另一个 Perl 选项是将记录分隔符设置为“>”,一次读取两行,然后将换行符替换为制表符:

use Modern::Perl;

local $/ = '>';
do { s/\n/\t/; print }
  for <DATA>;

__DATA__
>00000_x1688514
TGCTTGGACTACATATGGTTGAGGGTTGTA
>00001_x238968
TGCTTGGACTACATATTGTTGAGGGTTGTA

输出:

>00000_x1688514 TGCTTGGACTACATATGGTTGAGGGTTGTA
>00001_x238968  TGCTTGGACTACATATTGTTGAGGGTTGTA

对于文件:

use Modern::Perl;
use autodie;

open my $inFile,  '<', 'inFile.txt';
open my $outFile, '>', 'outFile.txt';

local $/ = '>';
do { s/\n/\t/; print $outFile $_ }
  for <$inFile>;

close $inFile;
close $outFile;

希望这能帮助您!

1

一种方法:

perl -i -pe 's/\n/ / unless m/^[ACGT]+$/' FILENAME

这将对文件FILENAME进行原地编辑,在每一行中用空格替换不是A、C、G和T字符串的换行符。


perl -i -pe ...。在这里,你需要使用p开关而不是n开关。 - Chris Charley

0

使用 awk

awk '{ printf "%s", $0 (substr( $0, 1, 1 ) == ">" ? " " : ORS) }' infile

输出:

>00000_x1688514 TGCTTGGACTACATATGGTTGAGGGTTGTA
>00001_x238968 TGCTTGGACTACATATTGTTGAGGGTTGTA

0
在 Ruby 中我会使用类似这样的东西:
File.readlines('test.txt').map(&:strip).each_slice(2) do |row|
  puts row.join(' ')
end

输出结果为:

>00000_x1688514 TGCTTGGACTACATATGGTTGAGGGTTGTA
>00001_x238968 TGCTTGGACTACATATTGTTGAGGGTTGTA

0
一个更整洁的Python解决方案:
from itertools import izip

with open('test.txt') as inf, open('newtest.txt', 'w') as outf:
    for head,body in izip(inf, inf):
        outf.write(head.rstrip() + ' ' + body)

0
假设输入是真正的FASTA格式,您可以使用awkgetline函数:
awk '/^>/ { printf "%s ", $0; getline; print }' file.txt

输出:

>00000_x1688514 TGCTTGGACTACATATGGTTGAGGGTTGTA
>00001_x238968 TGCTTGGACTACATATTGTTGAGGGTTGTA

HTH


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接