For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > June 2007 > writung to file









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author writung to file
Vahid Moghaddasi

2007-06-21, 9:58 pm

Hi all,
I wrote the following simple code to sort UNIX's password file, it
works fine but I can only display the ouput on the stdout. How can I
make it write the output to a file?
Thanks,

#!/bin/perl -w
#
use strict;
open(myFILE, '|-','awk','-F:','s[$1]++==0' ) or die $!;
open(passwdFH, "passwd");
while (<passwdFH> ) { print myFILE; }
close(myFILE);
Chas Owens

2007-06-21, 9:58 pm

On 6/21/07, Vahid Moghaddasi <vahid.moghaddasi@gmail.com> wrote:
> Hi all,
> I wrote the following simple code to sort UNIX's password file, it
> works fine but I can only display the ouput on the stdout. How can I
> make it write the output to a file?
> Thanks,
>
> #!/bin/perl -w
> #
> use strict;
> open(myFILE, '|-','awk','-F:','s[$1]++==0' ) or die $!;
> open(passwdFH, "passwd");
> while (<passwdFH> ) { print myFILE; }
> close(myFILE);


Well, first you don't use awk inside of Perl. This is about as useful
as riding a bike on a bus.

#!/usr/bin/perl

use strict;
use warnings;

open my $out, '>', "outputfile"
or die "could not open outputfile: $!";

open my $in, '<', 'passwd'
or die "could not open passwd: $!";

my %h;
while (<$in> ) {
print $out $_ unless $h{(split ':')[0]}++;
}
Vahid Moghaddasi

2007-06-21, 9:58 pm

On 6/21/07, Chas Owens <chas.owens@gmail.com> wrote:
>
> Well, first you don't use awk inside of Perl. This is about as useful
> as riding a bike on a bus.
>

Thanks, that worked very well for me.
Beside the force of habit, awk was the only way I could get the
password file sorted unique and always keep *only* the first
occurrence of the duplicate UID and discard the second duplicate.
Thanks again.
usenet@DavidFilmer.com

2007-06-21, 9:58 pm

On Jun 21, 1:10 pm, chas.ow...@gmail.com (Chas Owens) wrote:
> print $out $_ unless $h{(split ':')[0]}++;


Just curious - why are you coding around possible duplicates? Can a
passwd file have duplicate entries?


--
The best way to get a good answer is to ask a good question.
David Filmer (http://DavidFilmer.com)


Yitzle

2007-06-21, 9:58 pm

You can get only the first unique occurance of UID's with a hash.
Untested code below. I'm assuming the file has a UID followed by a
home path seperated by whitespace.

my %data;
while(<$fileHandle> ) {
my($UID, $home) = split /\s/;
$data[$UID] = $home if ( ! defined $data[$UID] );
}
Vahid Moghaddasi

2007-06-22, 7:59 am

On 6/21/07, usenet@davidfilmer.com <usenet@davidfilmer.com> wrote:
> On Jun 21, 1:10 pm, chas.ow...@gmail.com (Chas Owens) wrote:
>
> Just curious - why are you coding around possible duplicates? Can a
> passwd file have duplicate entries?
>

This is a part of a larger code which does other things such as
merging a few /etc/passwd files together by appending at the bottom
and sort unique then place it back on /etc/passwd.
Chas Owens

2007-06-22, 7:59 am

On 6/21/07, Vahid Moghaddasi <vahid.moghaddasi@gmail.com> wrote:
> On 6/21/07, Chas Owens <chas.owens@gmail.com> wrote:
> Thanks, that worked very well for me.
> Beside the force of habit, awk was the only way I could get the
> password file sorted unique and always keep *only* the first
> occurrence of the duplicate UID and discard the second duplicate.
> Thanks again.


There is a script included in the Perl distribution called a2p. The
next time you are stumped in Perl, but know how to do it in awk, use
it to figure out a way to do it in Perl.

a2p -F:
a[$1]++==0
#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if $running_under_some_shell;
# this emulates #! processing on NIH machines.
# (remove #! line above if indigestible)

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
# process any FOO=bar switches

$[ = 1; # set array base to 1
$FS = ':'; # field separator from -F switch

while (<> ) {
@Fld = split(/[:\n]/, $_, -1);
print $_ if $a{$Fld[1]}++ == 0;
}

Now, this isn't pretty code, but it can give you a starting point.
The first nine lines are boilerplate and can be safely ignored. The
tenth line is a dangerous thing you should never do. It is being done
here to emulate awk's indexing method, but it will not be necessary in
your Perl code; just remember, Perl starts at zero. The eleventh line
is meaningless in this context (it is only useful if your awk code
referenced $FS at some point). The real meat is in lines thirteen
through sixteen and they are functionally equivalent to the code I
sent. The only real difference is that it is keeping a copy of the
fields for the life of loop in case later code (that does not exist)
wants to look at it.
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com