removing a line from a file

V

Vahid

Hi all,
I have the following sub which adds a line '$assign' before the
last line in a file if 'add' is passed to the sub. I need a little
help to remove the line containing $new_user in the else part of the
sub. Also any suggestion in making the sub better looking is
appreciated.
Thanks,
Vahid.

sub qmail_alias {
$assign="=$new_user:$new_user:$new_uid:$new_gid:$def_qmail/alias:-:$new_user\n";
$var_qmail_alias = "/var/qmail/alias/.qmail-$new_user";
if ($DEBUG) { print "Assign value: $assign\n" };
my ($action) = @_;
open (ASSIGN_TMP,"> /tmp/assign.tmp") || die "Could not create
temporary assign file:$?";
open (ASSIGN, '</tmp/assign') || die "Could not open assign file:$?";
if ($action eq "add") {
print "Making mail alias for $new_user\n";
while ($INP_LINE = <ASSIGN>) {
print ASSIGN_TMP "$assign" if eof;
print ASSIGN_TMP $INP_LINE;
}
system("cp /tmp/assign.tmp /tmp/assign");
open (ALIAS, "> $var_qmail_alias") || die "$?";
if ($DEBUG) { print "Trying to write to: $var_qmail_alias\n" };
print ALIAS "&$new_email\n";
close ALIAS;
close ASSIGN;
close ASSIGN_TMP;
} else {
print "Deleting alias for $new_user.\n";
unlink $var_qmail_alias;
# need to remove $new_user from ASSIGN file.
}
}
 
P

Paul Lalli

Vahid said:
I have the following sub which adds a line '$assign' before the
last line in a file if 'add' is passed to the sub. I need a little
help to remove the line containing $new_user in the else part of the
sub.

Please check the Perl FAQ *before* posting.
Also any suggestion in making the sub better looking is appreciated.

sub qmail_alias {
$assign="=$new_user:$new_user:$new_uid:$new_gid:$def_qmail/alias:-:$new_user\n";

You're either not using strict or defining variables no where near the
scope in which they are used. Either way, bad style.
$var_qmail_alias = "/var/qmail/alias/.qmail-$new_user";
if ($DEBUG) { print "Assign value: $assign\n" };

Don't out-dent this. Instead, "hide" the debug conditional at the end:
print "Assign value: $assign\n" if $DEBUG;

my ($action) = @_;
open (ASSIGN_TMP,"> /tmp/assign.tmp") || die "Could not create
temporary assign file:$?";

$? will not contain any useful information in that die() statement.
Use the three-argument form of open.
Use lexical filehandles rather than global barewords

open my $assign_tmp_fh, '>', '/tmp/assign.tmp' or
die "Could not create /tmp/assign.tmp: $!"
open (ASSIGN, '</tmp/assign') || die "Could not open assign file:$?";

Same as above

open my $assign, '<', '/tmp/assign' or die "Could not open /tmp/assign:
$!";
if ($action eq "add") {
print "Making mail alias for $new_user\n";
while ($INP_LINE = <ASSIGN>) {
print ASSIGN_TMP "$assign" if eof;

perldoc -q quoting
"What's wrong with always quoting "$vars"?"
print ASSIGN_TMP $INP_LINE;
}
system("cp /tmp/assign.tmp /tmp/assign");

Why are you shelling out? Why *aren't* you checking the return value
of the system call?

use File::Copy;
copy '/tmp/assign.tmp', '/tmp/assign' or die "Could not copy: $!";
open (ALIAS, "> $var_qmail_alias") || die "$?";

See above.
if ($DEBUG) { print "Trying to write to: $var_qmail_alias\n" };

See above.
print ALIAS "&$new_email\n";
close ALIAS;
close ASSIGN;
close ASSIGN_TMP;
} else {
print "Deleting alias for $new_user.\n";
unlink $var_qmail_alias;

unlink $var_qmail_alias or die "Could not unlink: $!";
# need to remove $new_user from ASSIGN file.

perldoc -q "delete a line"

You may also be interested in the "in-place editing" feature of perl
supplied by -i (see perldoc perlrun) or $^I (see perldoc perlvar)

Paul Lalli
 
T

Tad McClellan

Vahid said:
Also any suggestion in making the sub better looking is
appreciated.

sub qmail_alias {
$assign="=$new_user:$new_user:$new_uid:$new_gid:$def_qmail/alias:-:$new_user\n";


$assign = join(':',
"=$new_user",
$new_user,
$new_uid,
$new_gid,
"$def_qmail/alias",
'-',
$new_user
)
. "\n"; # I think


open (ASSIGN_TMP,"> /tmp/assign.tmp") || die "Could not create
temporary assign file:$?";
^^

I think you want the $! variable in your diag message rather
than the $? variable.

system("cp /tmp/assign.tmp /tmp/assign");


What if the cp fails?

!system('cp /tmp/assign.tmp /tmp/assign') or
die "could not copy temp file: $? ";

(note the "not" operator and the (now) correct variable to be examining.)
 
V

Vahid

Paul said:
perldoc -q "delete a line"

You may also be interested in the "in-place editing" feature of perl
supplied by -i (see perldoc perlrun) or $^I (see perldoc perlvar)
Thanks for the suggestions. It is hard to convert from ksh to perl.
I guess I have to start using Tie::File module.
Vahid.
 
U

usenet

Vahid said:
I guess I have to start using Tie::File module.

Consider instead IO::All. This one module will do nearly everything you
would ever want to do with file (or even network) IO operations.

IO::All is actually a proxy for Tie::File (which is really invoked
"under the covers"), and the module is a proxy for several other
modules as well, and also nearly all of the Perl core IO functions.
The great thing about IO::All is that you can learn to use just one
module, instead of several functions and modules (some of which may be
rather esoteric, such as File::Find).

Consider this example, in which IO::All (acting as a proxy for
Tie::File) appends a line of text onto a file:

#!/usr/bin/perl
use strict; use warnings;
use IO::All;
push @{io "/tmp/foo.txt"}, "Last line";
__END__

Note that basic error handling is provided for you by the IO::All
module (so nobody here will fuss at me for not checking return codes).

Waxing eloquent on the wonders of the IO::All module with a favorite
example:
Suppose you want to list all *.txt (case insensitive) files recursed
only two directories deep (hah!) which are smaller than 1000 bytes and
whose first line contains the string "spooler" (case sensitive):

#!/usr/bin/perl
use strict; use warnings;
use IO::All;

my $root_dir = "/tmp";
print map {"$_\n"}
io($root_dir) -> filter(sub { $_->name =~ /\.txt$/i
&& $_->size < 1000
&& ($_->head)[0] =~ /spooler/
} )
-> all_files(2);
__END__
 
D

Dave Weaver

Vahid said:
...
system("cp /tmp/assign.tmp /tmp/assign");
open (ALIAS, "> $var_qmail_alias") || die "$?";
if ($DEBUG) { print "Trying to write to: $var_qmail_alias\n" };
print ALIAS "&$new_email\n";
close ALIAS;
close ASSIGN;
close ASSIGN_TMP;


Your "cp" command is happening before you close the file you're
copying. Perhaps not the best sequence of events.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top