Jump to content

print to indirect filehandle


Recommended Posts

I've go the following code:

 

#!/usr/bin/perl -w

$input1 = "input1.txt";
open (FH1, "< $input1") or die "Can't open $file for read: $!";
@old_review_list = <FH1>;
close FH1 or die "Cannot close $file: $!"; 	
for (@old_review_list) {
open ($old_review_list[$_],"> $_") || die "Can't open $_\n";

}

Basically right now it creates some files that it got names for from the array (@old_review_list). The next thing I need it to print some text into the files. Because I'm using indirect filehandles doing

print somefilehandle "a bunch of text.";

won't work.

 

to figure out whats next.

Share this post


Link to post
Share on other sites

Either you're confused or I am. old_review_list is an array of filenames, not file handles. Using open() with a filename will get a file handle, which you can then use with print() and close() just fine.

 

$input1 = "input1.txt";
open (FH1, "< $input1") or die "Can't open $file for read: $!";
  @old_review_list = <FH1>;
close FH1 or die "Cannot close $file: $!";

foreach $filename (@old_review_list) {
  open FH2,"> $filename" || die "Can't open $_\n";
  print FH2 "Hello World";
  close FH2 || die "Oh no!";
}

Share this post


Link to post
Share on other sites

OK lemme rethink this again.

 

What we need:

 

1. create & open the files that came from the array.

 

2. write to each of them.

 

3. close the files.

 

yes I could use a normal print ect, if I know what the filehandles are, but I don't.

Share this post


Link to post
Share on other sites

OK lemme rethink this again.

 

What we need:

 

1. create & open the files that came from the array.

 

2. write to each of them.

 

3. close the files.

 

yes I could use a normal print ect, if I know what the filehandles are, but I don't.

 

Read the code above again. You don't need to know what the file handles for each file are. You get the file handle (FH2) from using open() with a file name.

 

You have a list of file names you want to open, read from input1.txt, in old_review_list. So all you do is loop through each item in old_review_list (each file name) and use open() with the current item (which is a file name). This will get the file handle (FH2), which you can use as normal with print() and close().

Edited by markiemrboo

Share this post


Link to post
Share on other sites

can I get I quick example please my brain is turned to mush.

 

:lol: The code I posted should do exactly what you're trying to do. Here's the code with comments so you can try and follow what is happening.

 

#
# The file 'input1.txt' contains a list of file names, each file name on a new line.
#
$input1 = "input1.txt";
open (FH1, "< $input1") or die "Can't open $file for read: $!";
  #
  # input1.txt is opened and each line is entered in to the array old_review_list.
  # Therefore, each item in the array is a file name. 
  #
  @old_review_list = <FH1>;
close FH1 or die "Cannot close $file: $!";

#
# Loop through old_review_list one by one and put each item in to the variable filename.
#
foreach $filename (@old_review_list) {
  #
  # Open each file in old_review_list by the file name using the variable FH2 to temporarily store the handle of each file.
  #
  open FH2,"> $filename" || die "Can't open $_\n";
  #
  # Write to the file using the file handle that open provided.
  #
  print FH2 "Hello World";
  #
  # Close the file handle and go to the next item in the array
  #
  close FH2 || die "Oh no!";
}

 

 

Thanks

 

No problem. If you still don't get it then just say. I will explain again and again till you do :P

Share this post


Link to post
Share on other sites

GAH! that was way to easy.

 

Next issue; How about putting the output files in a directory. This:

opendir(work, "/tmp") || die "can't open /tmp: $!";

 

Spits out:

C:\Users\Jeff Loper\Documents\perl_redirect>perl test5.pl

can't open /tmp: No such file or directory at test5.pl line 15.

 

yes I made the dir.

Share this post


Link to post
Share on other sites

GAH! that was way to easy.

 

Next issue; How about putting the output files in a directory. This:

opendir(work, "/tmp") || die "can't open /tmp: $!";

 

Spits out:

 

yes I made the dir.

 

You're on Windows but using UNIX like file system addressing. I think that might also end up confusing you. Where have you made this tmp folder? C:\tmp? Then try "c:\\tmp" (I think, I haven't used perl on windows). If tmp is in the same directory as the script I would think you could probably do ".\tmp" or "./tmp" might even work...

Share this post


Link to post
Share on other sites

Next problem: the second function I need to to also look through input 2, which will fill in print "header(\"Location: http://www.overclockersclub.com/reviews/...");";

 

The purpose of this project is to make a bunch of http 301 redirects.

 

This is the actual text I need to print:

header("HTTP/1.1 301 Moved Permanently");

header("Location: http://www.overclockersclub.com/reviews/$name");

//add close header for IE"

header ("Connection: close");

?>

 

i know the quotes will need to be escaped using \ but i left that out for clarity.

Share this post


Link to post
Share on other sites

Multiple lines would probably be the place to use a heredoc. END shouldn't be indented, otherwise it will complain about not finding the string terminator. You can still use perl variables inside a heredoc, so you should also still be ok with $name.

 

$the_string = <<END;
<?
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://www.overclockersclub.com/reviews/$name");
//add close header for IE"
header ("Connection: close");
?>
END

print FH2 $the_string;

Share this post


Link to post
Share on other sites

Ok but what tweaks do I need to make to the loop in order to substitute the stuff from input2 into $name?

#

$input1 = "input1.txt";
$input2 = "input2.txt";
open (FH1, "< $input1") or die "Can't open $file for read: $!";
open (FH2, "< $input2") or die "Can't open $file for read: $!";
  #
  # input1.txt is opened and each line is entered in to the array old_review_list.
  # Therefore, each item in the array is a file name.
  #
  @old_review_list = <FH1>;
@new_review_list = <FH2>;
close FH1 or die "Cannot close $file: $!";
close FH2 or die "Cannot close $file: $!";

#
# Loop through old_review_list one by one and put each item in to the variable filename.
#
chdir tmp;
foreach $filename (@old_review_list) {
  #
  # Open each file in old_review_list by the file name using the variable FH2 to temporarily store the handle of each file.
  #
  open FH3,"> $filename" || die "Can't open $_\n";
  #
  # Write to the file using the file handle that open provided.
  #
print "<?";
print "header(\"HTTP/1.1 301 Moved Permanently\");";
print "header(\"Location: http://www.overclockersclub.com/reviews/$name\");";
print "//add close header for IE";
print "header (\"Connection: close\");";
print "?>";
  # Close the file handle and go to the next item in the array
  #
  close FH3 || die "Oh no! $!";
}

Share this post


Link to post
Share on other sites

Change the foreach to a plain for loop so you can have an index to use on both of your arrays I guess.

 

Pseudo-code-ish... because I shouldn't really be the one writing code for you :D

for (i = 0; i < size_of_one_of_the_arrays; i++)
{
  filename = array1[i];
  redirect_name = array2[i];
  ....
}

 

Another simple option would be to set a simple file format, initially read from one file and use a 3d type array. So the file might look like:

 

file1.txt,redirect_name

file2.txt,redirect_name2

 

Which would end up being put in to an array like (where = is stating the contents of the array):

 

array[0][0] = file1.txt

array[0][1] = redirect_name

array[1][0] = file2.txt

array[1][1] = redirect_name

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...