I'm not quite sure what you want to do with the files, but reading the file in a two-dimensional array can be done this way:
use warnings;
use strict;
open my $filehandle, "<", "filename.bed" or die "open: $!\n";
my @data;
while (<$filehandle>) {
chomp; # remove the line ending character
push @data, [ split /\t/ ]; # split the rest and append it to our dat
+a
};
print $data[0]->[0];
# access the first element of the array
# it's a reference, "->" dereferences it
# at last, access the first element of the dereferenced array
Here the [] brackets create an anonymous array reference (not just an array) filled with the return value of split and this reference (which is a scalar value, so it can be stored in the array) is pushed to the array.
You can always use Data::Dumper to print the contents of your data structure. Read perlreftut and perldsc for more information on references and complex data structures.
Edit: forgot to chomp
Sorry if my advice was wrong.
| [reply] [d/l] [select] |
If you are looking to put them in order, then you are better off using a hash of hashes (with an array :) ). For instance:
#!/usr/bin/perl
use warnings;
use strict;
my $usage = "merge_bed.pl <input1> <input2> <output>";
my $input_1 = shift or die $usage;
my $input_2 = shift or die $usage;
my $output = shift or die $usage;
open my $in1, "<", "$input_1" or die "Cannot open $input_1: $!\n";
open my $in2, "<", "$input_2" or die "Cannot open $input_2: $!\n";
open my $out, ">", "$output" or die "Cannot open $output: $!\n";
my %bed_files = ();
while ( <$in1> ) {
chomp;
my ($chrom, $start, $end, undef, undef, $strand) = split "\t";
$bed_files{$chrom}{$start}[0] = $end; # you can save multiple valu
+es as an array, so both the end and strand and anything else you want
$bed_files{$chrom}{$start}[1] = $strand;
}
while ( <$in2> ) {
chomp;
my ($chrom, $start, $end, undef, undef, $strand) = split "\t";
$bed_files{$chrom}{$start}[0] = $end;
$bed_files{$chrom}{$start}[1] = $strand;
}
for my $chrom (sort keys %bed_files) {
for my $start (sort {$a <=> $b} keys %{$bed_files[$chrom}}) {
# print out the results sorted by chromosome (or scaffold) and
+ start site
print $out "$chrom\t$start\t$bed_files{$chrom}{$start}[0]\t$be
+d_files{$chrom}{$start}[1]\n";
}
}
close $in1;
close $in2;
close $out;
exit;
This assumes that your lists don't have a) some of the same start sites and b) that there are not overlaps. If you want to find overlaps, then you can do the same thing, but have two separate data structures; you can find the overlaps, and then output the unique regions and one copy of the overlapping regions. There are ways to do this using an index (so it's faster and you only make one pass instead of looping though the entire bed file multiple times).
You could create function for code generating the main data structure, but I left it as is just so it's easier to read and see what I'm doing. Have fun!
EDIT: Fixed a couple of typos!
| [reply] [d/l] |
Can you explain the $usage and "shift or die" part?
| [reply] |
shift here shifts from the @ARGV array. If it fails, (if not enough file names, 3, were supplied on the command line), then the program dies, (quits), and prints the string contained in $usage, ("merge_bed.pl <input1> <input2> <output>". (This message tells the user that his perl program, merge_bed.pl or whatever name you choose as your program name requires 2 input filenames and 1 output name).
| [reply] [d/l] [select] |
Can you explain the $usage and "shift or die" part?
If you employ Basic debugging checklist (deparse,print) you can figure it out pretty quick :)
| [reply] |
This post finds overlapping .bed files, if that helps.
The link above will find overlapping ranges. If you just want to list both .bed files in sorted order, then the following will do it.
#!/usr/bin/perl
use strict;
use warnings;
use 5.014;
@ARGV = qw/ 148N.txt 162N.txt 174N.txt 175N.txt /;
my @data = map {[split]}
map {$_->[0]}
sort {$a->[1] <=> $b->[1] || $a->[2] <=> $b->[2] || $a->[3]
+<=> $b->[3]}
map {[ $_, /\d+/g]} <>;
say "@$_" for @data;
Ouput from the 4 files (in sorted order):
C:\Old_Data\perlp>perl t6.pl
chr1 10 50
chr1 12 40
chr1 20 45
chr1 25 30
chr1 25 50
chr1 41 45
chr1 48 80
chr1 60 80
chr1 100 500
chr10 10 20
Update: changed the sort and made simpler and still correct. .bed file definition from here. | [reply] [d/l] [select] |
UPDATE: My solution deleted as the solution of aitap is much nicer and explains the building blocks better. A ++ for the nice explanation.
McA
| [reply] |