user2131116
user2131116

Reputation: 2861

How to write a correct name using combination of variable and string as a filehandler?

I want to make a tool to classify each line in input file to several files but it seems have some problem in naming a filehandler so I can't go ahead , how do I solve?

here is my program

ARGV[0] is the input file
ARGV[1] is the number of classes

#!/usr/bin/perl

use POSIX;
use warnings;

# open input file
open(Raw,"<","./$ARGV[0]") or die "Can't open $ARGV[0] \n";

# create a directory class to store class files
system("mkdir","Class");

# create files for store class informations
for($i=1;$i<=$ARGV[1];$i++)
{
    # it seems something wrong in here
    open("Class$i",">","./Class/$i.class") or die "Can't create $i.class \n";
}

# read each line and random decide which class to store
while( eof(Raw) != 1)
{
    $Line = readline(*Raw);
    $Random_num = ceil(rand $ARGV[1]);
    for($k=1;$k<=$ARGV[1];$k++)
    {   
        if($Random_num == $k)
        {
                    # Store to the file
            print "Class$k" $Line;
            last;
        }
    }
}
for($h=1;$h<=$ARGV[1];$h++)
{
    close "Class$h";
}

close Raw;

thanks

Later I use the advice provided by Bill Ruppert

I put the name of filehandler into array , but it seems appear a syntax bug , but I can't correct it I label the syntax bug with ######## A syntax error but it looks quite OK ########

here is my code

#!/usr/bin/perl

use POSIX;
use warnings;
use Data::Dumper;

 # open input file
open(Raw,"<","./$ARGV[0]") or die "Can't open $ARGV[0] \n";

 # create a directory class to store class files
system("mkdir","Class");

# put the name of hilehandler into array
for($i=0;$i<$ARGV[1];$i++)
{
    push(@Name,("Class".$i)); 
}

# create files of classes
for($i=0;$i<=$#Name;$i++)
{
    $I = ($i+1);
    open($Name[$i],">","./Class/$I.class") or die "Can't create $I.class \n";
}

# read each line and random decide which class to store
while( eof(Raw) != 1)
{
    $Line = readline(*Raw);
    $Random_num = ceil(rand $ARGV[1]);
    for($k=0;$k<=$#Name;$k++)
    {   
        if($Random_num == ($k+1))
        {

            print $Name[$k] $Line;  ######## A syntax error but it looks quite OK ########
            last;
        }
    }
}
for($h=0;$h<=$#Name;$h++)
{
    close $Name[$h];
}

close Raw;

thanks

Upvotes: 1

Views: 123

Answers (2)

walker huang
walker huang

Reputation: 7

How about this one:

#! /usr/bin/perl -w
use strict;
use POSIX;

my $input_file = shift;
my $file_count = shift;
my %hash;

open(INPUT, "<$input_file") || die "Can't open file $input_file";

while(my $line = <INPUT>) {
    my $num = ceil(rand($file_count));
    $hash{$num} .= $line
}

foreach my $i (1..$file_count) {
    open(OUTPUT, ">$i.txt") || die "Can't open file $i.txt";
    print OUTPUT $hash{$i};
    close OUTPUT;
}

close INPUT;

Upvotes: 0

jwodder
jwodder

Reputation: 57490

To quote the Perl documentation on the print function:

If you're storing handles in an array or hash, or in general whenever you're using any expression more complex than a bareword handle or a plain, unsubscripted scalar variable to retrieve it, you will have to use a block returning the filehandle value instead, in which case the LIST may not be omitted:

print { $files[$i] } "stuff\n";

print { $OK ? STDOUT : STDERR } "stuff\n";

Thus, print $Name[$k] $Line; needs to be changed to print { $Name[$k] } $Line;.

Upvotes: 3

Related Questions