lomSpace has asked for the wisdom of the Perl Monks concerning the following question:
Hello,
I am trying to append the contents of three files to another file. I am only appending the strings from my regex and not the actual contents of the files. My code
#!/usr/bin/perl
use strict;
use Data::Dumper;
use File::Glob ':glob';
my @dirs = glob("C:/Documents and Settings/mydir/Desktop/KOMP/*");
foreach my $maid_dir(@dirs){
if (-d $maid_dir){ # directory check
if ($maid_dir=~m%\d+\s[A-Z]%){ # match the dir name
my $seq_dir = $maid_dir."/sequencing/";
chdir ($maid_dir);
next if (-M $seq_dir > 1.0);
chdir ($seq_dir);
#print Dumper ($maid_dir, $seq_dir);
opendir my $dh, "$seq_dir";
if(-d $seq_dir){
my @files = readdir $dh;
#my $path = @_;
for my $f(@files){
if($f=~ m%^(\d*)(HU.fa|HD.fa|Ltvec_small.FA|_fasta
+)$%){
my ($fa, $hu, $hd, $lt)= ($1."_fasta", $1."HU.
+fa", $1."HD.fa", $1."Ltvec_small.FA");
if(-e $fa){
open( my $in, ">>".$seq_dir."/".$fa);
#open( my $out, ">>".$seq_dir."/".$fa);
print $in, "\n" ;#"$hu,$hd,$lt\n";
print Dumper($f);
close($in);
}
}
}
}
}
}
}
gets me into the proper dir to access the files but I am doing something stupid. Any ideas?
Re: appending to a file
by Fletch (Bishop) on Mar 19, 2009 at 16:38 UTC
|
Not checking the return value from things like chdir, opendir, or open certainly could be considered stupid.
The cake is a lie.
The cake is a lie.
The cake is a lie.
| [reply] |
|
fletch++
To give a more direct example of what Fletch is talking about, do you know what happens in this piece of code if the change directory does not exist?
my $dir = "/my/working/directory";
chdir ( $dir );
system ("rm -rf *");
| [reply] [d/l] |
|
This removes everything in the dir.
| [reply] |
|
| [reply] |
|
It will always give you a glob memory address
#!/usr/bin/perl --
use Data::Dumper;
use strict;
use warnings;
opendir my $dh, "doesnotexist.mustnotexist";
print Dumper( $dh);
__END__
$VAR1 = \*{'::$dh'};
D:\dev\misc>
D:\dev\misc>perl
#!/usr/bin/perl --
use Data::Dumper;
use strict;
use warnings;
for my $dir( "doesnotexist.mustnotexist", "."){
opendir my $dh, $dir;
Parentheses missing around "my" list at - line 7.
print "dir $dir ", Dumper( $dh);
}
__END__
dir doesnotexist.mustnotexist $VAR1 = \*{'::$dh'};
dir . $VAR1 = \*{'::$dh'};
system calls can fail for any reason | [reply] [d/l] |
Re: appending to a file
by lostjimmy (Chaplain) on Mar 19, 2009 at 17:29 UTC
|
print $in, "\n" ;#"$hu,$hd,$lt\n"
which I'm assuming you were originally trying to print what is in comments.
What you would really want is:
print $in "$hu,$hd,$lt\n"; # no comma between $in and "..."
Other important things:
- Check errors after everything (chdir, open, opendir, close). If that doesn't work, you can even make sure print completed successfully.
- You should make more use of string interpolation. It would make your code cleaner. That is, use open my $in, ">>$seq_dir/$fa" instead.
- It's generally considered better form to use the three argument version of open, so change your open lines to open my $in, ">>", "$seq_dir/$fa"; and similar.
| [reply] [d/l] [select] |
Re: appending to a file
by Nkuvu (Priest) on Mar 19, 2009 at 16:41 UTC
|
I'd start with error checking. (added: Fletch is more accurate than I am on the functions you'll want to check errors on, consider adding similar error checking to the functions mentioned): open( my $in, ">>".$seq_dir."/".$fa) or die "Unable to open $seq_dir/$fa for append: $!\n"; Obviously if the file is read only or the path isn't parsed correctly, the open call will fail and you won't be able to write to the file.
| [reply] [d/l] |
|
I can append to the file, but am having trouble accessing the file contents. I am appending the file names not the contents. Example
13132HU.fa,13132HD.fa,13132Ltvec_small.FA
13132HU.fa,13132HD.fa,13132Ltvec_small.FA
13132HU.fa,13132HD.fa,13132Ltvec_small.FA
13132HU.fa,13132HD.fa,13132Ltvec_small.FA
This is what is being appended to the file. I want the contents of those files to be appended to the file.
Any ideas?
| [reply] |
|
I can't see how that's possible. The only thing you append to the file is a newline.
Here's a guess on what you're really looking for. You want to append the three files to the $fa file. You'll need to open each in turn, read from it, then print the contents to the $fa file (those variable names could really be more descriptive, by the way).
So I think what you want is something like this:
#!/usr/bin/perl
use strict;
use Data::Dumper;
use File::Glob ':glob';
my @dirs = glob("C:/Documents and Settings/mydir/Desktop/KOMP/*");
foreach my $maid_dir (@dirs) {
# Combined the first two conditionals to reduce indentation
if (-d $maid_dir and $maid_dir=~m%\d+\s[A-Z]%){ # match the dir na
+me
my $seq_dir = $maid_dir."/sequencing/";
chdir ($maid_dir) or die "Can't chdir to $maid_dir: $!\n";
next if (-M $seq_dir > 1.0);
chdir ($seq_dir) or die "Can't chdir to $seq_dir: $!\n";
#print Dumper ($maid_dir, $seq_dir);
opendir my $dh, "$seq_dir" or die "Can't open $seq_dir: $!\n";
if(-d $seq_dir){
my @files = readdir $dh;
#my $path = @_;
for my $f(@files){
if($f=~ m%^(\d*)(HU.fa|HD.fa|Ltvec_small.FA|_fasta)$%)
+{
my ($fa, $hu, $hd, $lt)= ($1."_fasta", $1."HU.fa",
+ $1."HD.fa", $1."Ltvec_small.FA");
if(-e $fa){
# This is output, not input. Renamed variable
+accordingly.
open( my $out, ">>".$seq_dir."/".$fa) or die "
+Can't open $seq_dir/$fa for append: $!\n";
# Append the contents of the three files to $f
+a
open my $hu_file, '<', $hu or die "Can't open
+$hu: $!\n";
while (my $line = <$hu_file>) {
print $out $line;
}
open my $hd_file, '<', $hd or die "Can't open
+$hd: $!\n";
while (my $line = <$hd_file>) {
print $out $line;
}
open my $lt_file, '<', $lt or die "Can't open
+$lt: $!\n";
while (my $line = <$lt_file>) {
print $out $line;
}
#open( my $out, ">>".$seq_dir."/".$fa);
print $out, "\n" ;#"$hu,$hd,$lt\n";
print Dumper($f);
close($out);
close($hu_file);
close($hd_file);
close($lt_file);
}
}
}
}
}
}
Note that this is a very quick revision of your code, with added error checks (and just noticed I missed the readdir, doh). And it may not be at all what you want. If not, please provide more detail on what you're trying to do. | [reply] [d/l] [select] |
|
|
|
The file test has not failed
| [reply] |
|
| [reply] [d/l] |
A reply falls below the community's threshold of quality. You may see it by logging in.
|
|
|