removing a line from a file

Discussion in 'Perl Misc' started by Vahid, Jan 4, 2006.

  1. Vahid

    Vahid Guest

    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.
    }
    }
    Vahid, Jan 4, 2006
    #1
    1. Advertising

  2. Vahid

    Paul Lalli Guest

    Vahid wrote:
    > 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
    Paul Lalli, Jan 4, 2006
    #2
    1. Advertising

  3. Vahid <> wrote:

    > 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.)


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jan 4, 2006
    #3
  4. Vahid

    Vahid Guest

    Paul Lalli wrote:
    >
    > 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.
    Vahid, Jan 4, 2006
    #4
  5. Vahid

    Guest

    Vahid wrote:
    > 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__


    --
    http://DavidFilmer.com
    , Jan 4, 2006
    #5
  6. Vahid

    Dave Weaver Guest

    Vahid <> wrote:
    > ...
    > 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.
    Dave Weaver, Jan 10, 2006
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hugo
    Replies:
    10
    Views:
    1,292
    Matt Humphrey
    Oct 18, 2004
  2. Chris  Chiasson
    Replies:
    6
    Views:
    606
    Richard Tobin
    Nov 14, 2006
  3. kaushikshome
    Replies:
    4
    Views:
    753
    kaushikshome
    Sep 10, 2006
  4. scad
    Replies:
    23
    Views:
    1,146
    Alf P. Steinbach
    May 17, 2009
  5. Marek Stepanek
    Replies:
    12
    Views:
    401
    Peter J. Holzer
    Sep 2, 2006
Loading...

Share This Page