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

Fellow Monks,

my cubemate (for interesting reasons which are not relevent here) needed some way to make an automated update to his source files (java). the particular edit was to simply add a single blank line to the top of the file. He has a large list of files to do this to.

I was asked if I could think of a solution different than his, which was a vi trigger (that works quite nicely in fact). Being humbled and enlightened by his solution, I felt obligated to share a solution using Perl.

so I set forth to create a perl one-liner to accomplish this goal. Note this is my second attempt to do such a thing...i.e. assist a co-worker not exposed at all in perl by creating a one-liner to solve the problem. (what better way to show off the power of perl, than a neat one-liner?). My first attempt is documented in the Monastery here: Quick solutions to easy problems

while I did not accomplish the goal of the one-liner in the above situation, I did solve the problem. And by posting, I rec'd a few real one-line solutions (many thanks to tilly, merlyn).

In this case, I was close for some time, but could not get this (or some other solutions) to work against multiple files. then I found (RTFM) that <> never does an explicit close (so $. was not being re-initialized) and success was at hand.

So I post my successful one-liner in anticipation of more elegent solutions being posted, as we all know TIMTOWTDI, and those other ways will surely result in a solution that requires a bit less typing ;-)

xdev$ cat foo line 1 line 2 line 3 xdev$ cat foo1 line 1 line 2 line 3 xdev$ perl -i.bak -ne 'if ($.==1){print "\n";}print;if (eof){close ARG +V;}' foo* xdev$ cat foo line 1 line 2 line 3 xdev$ cat foo1 line 1 line 2 line 3 xdev$

Replies are listed 'Best First'.
Re: Yet another one-liner
by danger (Priest) on Jan 12, 2001 at 01:09 UTC

    And yet another way to do it:

    perl -pi.bak -e 's/^/\n/ if 1..1;$.=0 if eof' foo*
Re: Yet another one-liner
by mirod (Canon) on Jan 12, 2001 at 00:41 UTC

    Why use -n and not -p here?:

    perl -i.bak -pe 'print "\n" if($.==1)'

    or in the Perl Golf spirit:

    perl -i.bak -pe 's/^/\n/ if($.==1)'

    Update:Darn! fundflow is right! So let's try:

     perl -i.bak -pe 's/^/\n/ if(!$a); $a= !eof'

    This one should work fine

      this doesn't work as $. isn't reset after each file:
      perl -pe 'print "$. "' file1 file2 1 2 1 3 2 4 3 5 1 6 2 7 3 [
      Is this a bug? I'm using v. 5.6.0

        That is why you need the explicit close that the original poster included. Good catch!

                - tye (but my friends call me "Tye")
Re: Yet another one-liner
by fundflow (Chaplain) on Jan 12, 2001 at 00:46 UTC
    Since it seems like you are using unix, here is a non-perlish solution:
    (echo ""; cat foo1) > foo1.new
    And for many files (in tcsh):
    foreach f ( foo* ) (echo ""; cat $f) > $f.new end
Re (tilly) 1: Yet another one-liner
by tilly (Archbishop) on Jan 12, 2001 at 00:49 UTC
    TMTOWTDI:
    perl -pi.bak -e 'BEGIN{undef $/} print "\n"' foo*
    UPDATE
    I am a little confused at what one-line solution I gave you. :-)
      Fore!
      perl -pi.bak -e 'BEGIN{$/=$u}s//\n/' foo*
      PS Clarification on my update above. I don't remember giving any hints on how to do this as a one-liner.

      UPDATE
      Obvious improvement. Dropped the $ off of the u.

      UPDATE 2
      Um, without it you can add a return to the end of the file as well. The $ is back.

        Learn to love all of Perl's command line options! perl -pi.bak -0es//\\n/ foo* :)

        (Update: If your files may contain null characters, make that perl -pi.bak -0777es//\\n/ foo* instead.)

        tilly, your version:

        perl -pi.bak -e 'BEGIN{$/=$u}s//\n/' foo*

        Works fine with 5.00503, but with 5.6.0 it appends an extra newline to the file:

        $ cat > XXX 1 2 3 $ cp XXX fxx $ perl5.00503 -pi.bak -e 'BEGIN{$/=$u}s/^/\n/' fxx* $ cat fxx 1 2 3 $ cp XXX fxx $ perl5.6.0 -pi.bak -e 'BEGIN{$/=$u}s/^/\n/' fxx* $ cat fxx 1 2 3 $

        Curious.