Commit patch to not break on spaces.
[bowtie.git] / scripts / fastq_to_tabbed.pl
1 #!/usr/bin/perl -w
2
3 ##
4 # fastq_to_tabbed.pl
5 #
6 # Convert a pair of FASTQ files to a single file in a one-pair-per-line
7 # format, where each line has these five tab-delimited fields:
8 #
9 # 1. Pair name
10 # 2. Sequence of mate 1
11 # 3. Qualities of mate 1
12 # 4. Sequence of mate 2
13 # 5. Qualities of mate 2
14 #
15 # This script comes in handy if (a) you'd just like to store your
16 # paired-end data in a less awkward format than the usual pair of
17 # parallel FASTQ files, or (b) you'd like to use Bowtie with gzipped
18 # paired-end input without unzipping it first.  In that case, you can
19 # pipe the output of this script (which handles gzipped inputs by
20 # piping them through gzip -dc) to Bowtie and use '--12 -'.
21 #
22 # Note that this script can also handle unpaired input (with -u), which
23 # Bowtie handles approrpaitely in --12 mode even when it's intermingled
24 # with paired-end input.
25 #
26
27 use strict;
28 use warnings;
29 use Getopt::Long;
30
31 # Courtesy: http://www.perlmonks.org/?node_id=625977
32 sub shuffle (@) {
33         my @a = \(@_);
34         my $n;
35         my $i = @_;
36         map {
37                 $n = rand($i--);
38                 (${$a[$n]}, $a[$n] = $a[$i])[0];
39         } @_;
40 }
41
42 my $unpaired = "";
43 my $mate1 = "";
44 my $mate2 = "";
45 my $shuffle = 0;
46
47 GetOptions ("u=s"     => \$unpaired,
48             "1=s"     => \$mate1,
49             "2=s"     => \$mate2,
50             "shuffle" => \$shuffle) || die "Bad option";
51
52 my @output;
53 my @unpaireds = split(/,/, $unpaired);
54
55 for my $f (@unpaireds) {
56         open UNP, "$f" || die;
57         while(<UNP>) {
58                 chomp;
59                 my $name = $_;
60                 $name = substr($name, 1);
61                 my $seq = <UNP>;
62                 chomp($seq);
63                 my $name2 = <UNP>;
64                 my $qual = <UNP>;
65                 chomp($qual);
66                 push @output, "$name\t$seq\t$qual\n";
67         }
68         close(UNP);
69 }
70
71 my @mate1s = split(/,/, $mate1);
72 my @mate2s = split(/,/, $mate2);
73
74 for(my $i = 0; $i <= $#mate1s; $i++) {
75         if($mate1s[$i] =~ /\.gz$/) {
76                 open M1, "gzip -dc $mate1s[$i] |" || die;
77         } else {
78                 open M1, "$mate1s[$i]" || die;
79         }
80         if($mate2s[$i] =~ /\.gz$/) {
81                 open M2, "gzip -dc $mate2s[$i] |" || die;
82         } else {
83                 open M2, "$mate2s[$i]" || die;
84         }
85         while(<M1>) {
86                 my $name1 = $_;
87                 chomp($name1);
88                 $name1 = substr($name1, 1, -2);
89                 my $name2 = <M2>;
90                 chomp($name2);
91                 $name2 = substr($name2, 1);
92                 my $seq1 = <M1>;
93                 chomp($seq1);
94                 my $seq2 = <M2>;
95                 chomp($seq2);
96                 my $tmp = <M1>;
97                 $tmp = <M2>;
98                 my $qual1 = <M1>;
99                 chomp($qual1);
100                 my $qual2 = <M2>;
101                 chomp($qual2);
102                 print "$name1\t$seq1\t$qual1\t$seq2\t$qual2\n" unless $shuffle;
103                 push @output, "$name1\t$seq1\t$qual1\t$seq2\t$qual2\n" if $shuffle;
104         }
105         close(M1);
106         close(M2);
107 }
108
109 if($shuffle) {
110         @output = shuffle(@output);
111         print join("", @output);
112 }