Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Command Switch -i prints to screen not file

by BillKSmith (Prior)
on Dec 29, 2020 at 16:56 UTC ( #11125944=perlquestion: print w/replies, xml ) Need Help??

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

I planned to recommend that skjeiu use the Command switch (-i~) in his solution to While loop not printing anything after using grep. My test case did not work as expected. The input file was correctly renamed as the backup. A new file was created with the original name. However, the print function sent its output to the screen rather than the file. What am I missing?
#!perl -i.bak my @input = <>; if (!scalar grep {/Friday/} @input) { splice @input, 1, 0, "Friday\n"; } print @input;

using Strawberry perl on windows 7

perl -v This is perl 5, version 30, subversion 2 (v5.30.2) built for MSWin32-x +64-multi-t hread

Replies are listed 'Best First'.
Re: Command Switch -i prints to screen not file
by ikegami (Pope) on Dec 29, 2020 at 17:41 UTC

    By using <ARGV> in list context, you read not only all of the first file, but all subsequent files as well. The file to which you want to write has already been closed and you've already moved on to the next file by the time you reach the print

    Read one file at a time:

    local $/; # One line = one file while (<>) { my @input = split /^/m; if (!grep {/Friday/} @input) { splice @input, 1, 0, "Friday\n"; } print @input; }
Re: Command Switch -i prints to screen not file
by haukex (Bishop) on Dec 29, 2020 at 18:04 UTC

    You may be interested to know that you can achive the effect of the -i command line switch from inside a script via $^I, for an example see my node here. That way you have more control over what happens than the shebang line. (However, the limitation that ARGVOUT gets closed after the my @input = <>; still applies.)

      Thanks to all for the explanation. I thought that this switch would add a useful, if not required, function with almost no code. Clearly this is not the case. If backup is desired, I would now recommend explicitly coding the steps described in the documentation of -i. Take care to put the close in the proper place.
        Allow me some comments ...

        I think putting command-line switches into the she-bang is not one of the better ideas, I doubt it's portable.

        HaukeX just offered an alternative special variable, which even has a full English name $INPLACE_EDIT which is also self documenting.

        And you've rather got bitten here by the effects of slurping the whole file into an array which is often a dangerous idea, because the size might be huge. I prefer lazy iteration by working line by line, whenever possible.

        And making a full copy in RAM first is rather the strategy when you intend to directly replace the content in the filesystem, so you somehow doubled the efforts to a paradox effect.

        Just my 2 cents ... :)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Re: Command Switch -i prints to screen not file (up-guessed)
by LanX (Cardinal) on Dec 29, 2020 at 17:36 UTC
    It's originally meant for command line use with -e.

    But you are trying to use it inside a script, right?


    I can't test right now, but my guess is that slurping the whole file first leads to a closing effect.

    I'd try editing line by line ...

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11125944]
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2021-04-14 09:11 GMT
Find Nodes?
    Voting Booth?

    No recent polls found