mabman has asked for the wisdom of the Perl Monks concerning the following question:

OK, I beg your indulgence - I'm away from my Perl books, I'm having a massive brain fart, and I can't seem to find the answer via any sort of searching.

What I want to do is search a text file for a line (or rather a part of a line), and then insert another line of text directly above it, after what is already entered there.

For instance, the text file might say:

(Settings)
foo=1
(baz-123)

and I want to ultimately end up with is:

(Settings)
foo=1
bar=2
(baz-123)

Also, the last line may change from file to file, eg, it may be (baz-456) or (baz-678) or whatever, but the "(baz" will be constant.

Thanks in advance,

Glenn

Replies are listed 'Best First'.
Re: insert line of text above a line
by Limbic~Region (Chancellor) on Sep 25, 2003 at 22:41 UTC
    Glenn,
    Assuming you only want to do this on the first match:
    #!/usr/bin/perl -w use strict; open (INPUT, "original") or die "Unable to open input file : $!"; open (OUTPUT, ">newfile") or die "Unable to open output file : $!"; select OUTPUT; my ($match, $replaced); while (<INPUT>) { $match = 1 if $_ =~ /baz/; if ($match && ! $replaced) { print "Replacement Line\n$_"; ($match, $replaced) = (0, 1); } else { print; } }
    It is then a simple matter of using rename or File::Copy to move the new file in place. You may also want to take a look at Tie::File as it can treat a file as an array.

    Cheers - L~R

      Excellent! That did it.

      Glenn

Re: insert line of text above a line
by BrowserUk (Patriarch) on Sep 25, 2003 at 23:17 UTC
    perl -pi.bak -e" /\(baz-\d+\)/ and print 'bar=2'.$/" file

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

      Okay -- but one needs to be careful about those quotes on the command line. In bash (or any bourne-like shell, whether on *nix or wintel), having the double-quotes on the outside (around the script) means that strings in the script that begin with "$" could be interpolated by the shell as environment variables (which might yield empty strings).

      The problem doesn't apply in this particular case, because shell variable names have to start with an alphanumeric ("$1" etc are shell variables); as a general rule, bourne-shell users habituate toward single quotes around perl one-liners on the command line. (I suppose with "command.com", the behavior may be different.) (update: for those, like Browser UK, who didn't know, "command.com" is the DOS/Windows executable that is the standard DOS command-line interface)

        What's command.com?


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
        If I understand your problem, I can solve it! Of course, the same can be said for you.

Re: insert line of text above a line
by Fletch (Bishop) on Sep 26, 2003 at 01:36 UTC

    See also perldoc -q "insert a line" (or search for the same in perldoc perlfaq5).

Re: insert line of text above a line
by flounder99 (Friar) on Sep 26, 2003 at 02:33 UTC
    I thought I might just mention Tie::File and a splice.

    --

    flounder

Re: insert line of text above a line
by BUU (Prior) on Sep 25, 2003 at 22:42 UTC
    uh..
    perl -pe"if($_eq'baz-123'){print'bar=2'}" old_file.txt > new_file.txt
      uh..

      C:\>perl -pe"if($_eq'baz-123'){print'bar=2'}" old > new String found where operator expected at -e line 1, near "123'){print'" (Missing operator before '){print'?) Bareword found where operator expected at -e line 1, near "'){print'ba +r" (Missing operator before bar?) String found where operator expected at -e line 1, at end of line (Missing semicolon on previous line?) syntax error at -e line 1, near "123'){print'" Can't find string terminator "'" anywhere before EOF at -e line 1.

      Why not use the -i command line option?
      Since baz is the only constant, it should be =~ /baz/ and not eq
      print 'bar=2' wtf is the newline?
      Thanks for broken code that would not do the job even if it worked

        So he forgot a space in $_hereeq, and he doesn't print a single newline, big f-ing deal (no need to be rude).