LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-14-2008, 05:33 AM   #1
wondergirl
LQ Newbie
 
Registered: Feb 2008
Posts: 18

Rep: Reputation: 0
Perl question


Hi all!
I have a perl-related question.

I have a file called printers, which has a list of printers in it :

cat printers :

sdt002_psr
sdt002_psr2
sdt002_psrt
sdt002d
sdt002dr
sdt002dr2
sdt002drt


Now I am wondering, if its possible to have an array statement like this :

@printers=(`cat /tmp/test_print1`);

I just dont want to use the other way (eg open (FH, "< $file") or die "Can't open $file for read: $!" and am wondering if its possible to do something like the above (cat), to populate the array?

Thanks in advance!
 
Old 02-14-2008, 05:57 AM   #2
Su-Shee
Member
 
Registered: Sep 2007
Location: Berlin
Distribution: Slackware
Posts: 510

Rep: Reputation: 53
@yourlist = `cat printerlist`; works, yes.
 
Old 02-14-2008, 06:23 AM   #3
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
that's not a portable way of doing things. anyway, that's your choice.
 
Old 02-14-2008, 07:13 AM   #4
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
If you know that the file "printerlist" has only a group of lines like that (one item per line, printer names only), you could also do something like this:
Code:
#!/usr/bin/perl
use warnings;
use strict;

my @printers;
while (<>) {
    chomp;
    push @printers, $_;
}

## Code here to work on @printers array ##
Save this as "printers_perl" and put the filename "printerlist" in the command line when you run it: ./printers_perl printerlist
 
Old 02-14-2008, 12:34 PM   #5
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by Telemachos View Post
If you know that the file "printerlist" has only a group of lines like that (one item per line, printer names only), you could also do something like this:
Code:
#!/usr/bin/perl
use warnings;
use strict;

my @printers;
while (<>) {
    chomp;
    push @printers, $_;
}

## Code here to work on @printers array ##
If you want to do that anyway, you could just slurp it:
Code:
chomp(my @printers=<>);

## Code here to work on @printers array ##
 
Old 02-14-2008, 01:18 PM   #6
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
Quote:
Originally Posted by osor View Post
If you want to do that anyway, you could just slurp it:
Code:
chomp(my @printers=<>);

## Code here to work on @printers array ##
Quicker - thanks for the tip.
 
Old 02-14-2008, 02:23 PM   #7
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Btw, the act of slurping a file without explicitly opening a filehandle and checking to make sure it opened is going to be a built-in feature in Perl 6 (whenever that gets released. You will also be able to specify automatic chomping.

So you will be able to do this:
Code:
my @printers = slurp('/tmp/test_print1', {chomp=>1});

## Code here to work on @printers array ##
If you want this in perl 5, you’ll need to “use Perl6::Slurp” to get the same functionality.
 
Old 02-14-2008, 11:13 PM   #8
wondergirl
LQ Newbie
 
Registered: Feb 2008
Posts: 18

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by osor View Post
If you want to do that anyway, you could just slurp it:
Code:
chomp(my @printers=<>);

## Code here to work on @printers array ##
Thanks for all the info!

'Slurping' doesnt work for me it looks like..?

I changed my script from

@printers=`cat printers`;
@print_servers=`cat print_servers`;

To

chomp(my @printers=<>);
chomp(my @print_servers=<>);

But when I ran the script it hung....whether I did something wrong here?

Thanks again!
 
Old 02-14-2008, 11:25 PM   #9
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Can you show us a short (but complete) version of your code which has that problem. It's difficult to just guess.


Incidentally, this version works as a demo:

my @t_arr = <>;
chomp(@t_arr);
print join("\n", @t_arr)."\n";
 
Old 02-14-2008, 11:29 PM   #10
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by wondergirl View Post
Thanks for all the info!

'Slurping' doesnt work for me it looks like..?

I changed my script from

@printers=`cat printers`;
@print_servers=`cat print_servers`;

To

chomp(my @printers=<>);
chomp(my @print_servers=<>);

But when I ran the script it hung....whether I did something wrong here?

Thanks again!
how did you run the script? did you provide a file name as input?
 
Old 02-15-2008, 03:47 AM   #11
wondergirl
LQ Newbie
 
Registered: Feb 2008
Posts: 18

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by ghostdog74 View Post
how did you run the script? did you provide a file name as input?
I basically have this in my script :

#/opt/perl/5.8.0/bin/perl

chomp(my @printers=<>);
chomp(my @print_servers=<>);

for my $i (0..$#printers) {
$hash{$printers[$i]} = $print_servers[$i];
}


use Data:umper;
print Dumper \%hash;

----------------

Then I ran it on the shell using 'perl filename' and it hung..

Thanks a lot for your help
 
Old 02-15-2008, 04:57 AM   #12
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Code:
# perl script.pl filename
also this, should be
Quote:
#/opt/perl/5.8.0/bin/perl
Code:
#!/opt/perl/5.8.0/bin/perl
 
Old 02-16-2008, 12:09 PM   #13
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by wondergirl View Post
chomp(my @printers=<>);
chomp(my @print_servers=<>);
So you want to slurp two separate files? Because of the way the default filehandle (“<>”) works, the first slurp will slurp the entirety of ALL the files specified in @ARGV. The second slurp will just wait for more input (presumably from STDIN). There are a few remedies to this problem:
  1. Go back to using the non-portable `cat filename` construct.
  2. Use Perl6::Slurp.
  3. Go about opening filehandles, and slurp them individually. This is not always as annoying as it seems:
    Code:
    my ($printers, $print_servers) = do {
    	open(my $pr, $ARGV[0]) && open(my $ps, $ARGV[1]) || die "$!";
    	([<$pr>], [<$ps>]);
    };
    
    # use $printers and $print_servers as array references (e.g., $printers->[0], etc.)
    So pretty much three lines, and it doesn’t look too bad. If you notice, $pr and $ps go out of scope after the block, so the files are automatically closed. A downside (not too problematic) is that you get array references instead of real arrays.
  4. Manipulate @ARGV, and then slurp. The default filehandle “<>” picks input from the files listed in @ARGV, and if there are no such files, then from STDIN. So if you manipulate @ARGV prior to slurping, you can control what happens to it. So (assuming you want the first file in @printers and the second in @print_servers), you might do something like:
    Code:
    my $temp=pop @ARGV;
    chomp(my @printers=<>);
    push(@ARGV,$temp);
    chomp(my @print_servers=<>);
    If you don’t want $temp to litter the namespace, you could probably pull off putting the construct in a “do” block.
  5. If you are sure that the files are the same size, you can use slices to access them directly:
    Code:
    chomp(my @both=<>);
    my @printers=@both[0..@both/2-1];
    my @print_servers=@both[@both/2..$#both];
    Obviously, this is the most error-prone (e.g., there will be no errors if you happen to be unable to read one of the files, or if you just forget to specify a file).
Btw, you can use hash-slicing to accomplish the same thing as your for loop. So this:
Code:
my %hash;
for my $i (0..$#printers) {
	$hash{$printers[$i]} = $print_servers[$i];
}
Is equivalent to this:
Code:
my %hash;
@hash{@printers}=@print_servers;

Last edited by osor; 02-16-2008 at 12:13 PM. Reason: typo
 
Old 02-16-2008, 12:43 PM   #14
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
I completely forgot a simpler (sort of) method: Have the first file as an argument and the second file redirected to STDIN. So you could do something like what you did before:
Code:
chomp(my @printers=<>);
chomp(my @print_servers=<>);
But instead of executing it like this:
Code:
perl script file1 file2
You could execute it like this:
Code:
perl script file1 < file2
Note that his hack will only work with two files, but the other methods I posted can be extended to the general case.
 
Old 02-17-2008, 12:10 PM   #15
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940
As a general rule, I like to look for CPAN-modules to do things like this, because the writers of those modules usually are thinking, "how can I do this in a portable, system-independent way?" If you port your program over to Windows, it won't run anymore. Maybe that is not a consideration; maybe it is.

Secondly... as you can see from this thread, "there's more than one way to do it." Pick one, comment it clearly, and make sure that it works in all of the present-and-future situations that your code is likely to encounter. Then, move along to the next objective in your project. "There's more than one way to do it," and you don't have to enumerate them.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Perl Question for perl hackers. linuxlover1 Programming 1 06-27-2006 06:56 PM
reinstall perl question.. (urpme perl) rjcrews Mandriva 2 01-28-2006 06:19 PM
Perl Question Whiteghost Linux - General 1 10-09-2005 03:52 PM
Hiding code in PERL, perl gui question randomx Programming 1 06-26-2004 03:22 PM
perl(Cwd) perl(File::Basename) perl(File::Copy) perl(strict)....What are those? Baldorg Linux - Software 1 11-09-2003 08:09 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:43 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration