in reply to problem with deleting a row

My reply is from the Perl Cookbook Modifying a File in Place with -i switch and it takes place all on the command line.

perl -i.orig -ne 'print unless /^lb348,/' test.txt
The original file is copied to test.txt.orig and the new file has all lines that do not begin (that's what the ^ anchor is for) with lb348 followed by a comma. (The -n says to loop over all the lines in the filenames given in the argument list, so this works on many files at once. The -e says to execute the bit of code between the quotes.)

If you're sysadmining, slinging files around as quick as you can, learning to use the command line will save you time.

Sometimes I can think of 6 impossible LDAP attributes before breakfast.

Replies are listed 'Best First'.
Re^2: problem with deleting a row
by brianMonk (Initiate) on Nov 21, 2013 at 17:10 UTC
    Ea, thanks very much for your code, it works. However, I have to make a script, not command line statement. And I done this:
    #!/usr/bin/perl -w open( FILE, "<", "test.txt") or die "cannot open > test.txt: $!"; while (<FILE>) { @array = <FILE>; @a = grep (/^lb348,/, @array); close FILE; print $a; }
    But it does not work. Sorry, I am new to programming.

      This:

      while (<FILE>) { @array = <FILE>;
      is just wrong. Either you read the file line by line with a while loop, or you "slurp" it into an array, but don't do both. The you are constructing a @a array and print $a, a scalar variable. The following pragmas:
      use strict; use warnings;
      would have picked up these errors.

      I've been writing Perl for 17 years and I'm still learning new and better ways to write code. Here's another way based on kcott's excellent answer below.
      #!/usr/bin/perl -w use strict; use autodie; my ($user_file, $changed_file) = qw{test.txt test.txt.mod}; open my $in_fh, '<', $user_file; open my $out_fh, '>', $changed_file; print "Which user? "; my $user = <STDIN>; chomp $user; print $out_fh grep !/^$user,/, <$in_fh>;
      This one slurps the whole file with the angle brackets, passes it through grep to filter the output which gets printed to the output file. Note the exclamation mark in front of the regex. It's the "not" operator which says you don't want the matching lines in your output.

      Keep working at it. From the long list of replies, you've certainly piqued the Monks' interest.

      Sometimes I can think of 6 impossible LDAP attributes before breakfast.
        print $out_fh grep !/^$user,/, <$in_fh>;

        As far as I can say, this does not work properly. Using the example under the Perl debugger I gave above in this post Re^5: problem with deleting a row, I obtain the following with your syntax:

        DB<3> $user = "foo"; DB<10> print join " ", grep !/^$user,/, qw /foo foobar bar barfoo fo +bar foobaz /; foo foobar bar barfoo fobar foobaz DB<11> print join " ", grep /^$user,/, qw /foo foobar bar barfoo fob +ar foobaz /; DB<12>
        This apparently does not work because $user is interpreted literally as a pattern. As I said in the post mentioned above, you need to force evaluation of $user into the content of the variable (I gave in that post two possible ways of doing that) to get this to work properly.

      Well I managed to do this. The code returns every line except the one that the user wants to delete entering first username. However, if in my test.txt file two usernames start with the same letter (for example, la123 and lv444), the program will remove both lines, regardless user input that is for example la123.
      $file = "test.txt"; print "Enter the username you want to remove from the information.txt +file\n"; $user = <STDIN>; open( FILE, $file) or die "cannot open > test.txt: $!"; while (<FILE>) { chomp; @array = <FILE>; @a = grep (!/^[$user]/, @array); print @a; }
        Why are you using square brackets around the $user variable? Don't forget to chomp $user.
        Lauren, if I remove square brackets around $user, the program will just output every line refusing to perform grep function.