http://www.perlmonks.org?node_id=1076103

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

Dear Monks
I have a perl oneliner which will add a line to the exisiting file after the 3 line, when i run this command from the command prompt it is perfectly adding a line, but when include the same command in script it is displaying error as "(might be runway multi-line " " starting on line 1) and execution -f -e aborted due to compilation error"
#!/usr/bin/perl `perl -ni -e 'print; print "adding value=key\n" if $.==3' myfile.txt`; + #from command prompt its works fine
Even i tried to assing this command to variable and tried to execute by system($cmd) still getting the same error, please correct my mistake.

Replies are listed 'Best First'.
Re: Problem in executing the perl oneliner within the script
by kcott (Archbishop) on Feb 25, 2014 at 08:48 UTC

    G'day perladdict,

    You've been here long enough to know about using the strict and warnings pragmata. Why don't you? In this instance, warnings would have told you:

    Use of uninitialized value $. in concatenation (.) or string at ...

    You've also been here long enough to know about posting actual error and warning messages, not some vague or incomplete version. Here's what your code actually produces:

    syntax error at -e line 2, near "if ==" (Might be a runaway multi-line "" string starting on line 1) Execution of -e aborted due to compilation errors.

    Backticks (`...`) are interpolating quotes: see perlop: Quote-Like Operators. The $. is interpolated as an "uninitialized value" (which warnings tells you); so "if $.==" becomes "if ==" (which the full error message tells you).

    That explains the problem; however, why are you starting another perl process? You're already running a perl process — just let it run the code.

    -- Ken

      Thanks Kcott, based on your detail description for the error message i modified the command as below.
      In our server there is no stricts and warning in stalled @INC hence unable to use this in my test script.
      @reports = `ls *.doc`; foreach $file(@reports) { $cmd=`perl -ni -e 'print;print "VALUE=KEY\n" if \$\.== 3;' $file` }
      The above code is working fine now, with this i can able to add a line to around 1400 report files.
        @reports = `ls *.doc`; foreach $file(@reports) { $cmd=`perl -ni -e 'print;print "VALUE=KEY\n" if \$\.== 3;' $file` }

        The above code is working fine now, with this i can able to add a line to around 1400 report files.

        That script will be creating ~1400 perl processes. You've been repeatedly advised about this yet you continue to do it.

        This script performs exactly the same function but only uses one perl process:

        #!/usr/bin/env perl -i use strict; use warnings; while (<>) { print; print "VALUE=KEY\n" if $. == 3; $. = 0 if eof; }

        I suggest you read "perlrun - how to execute the Perl interpreter". Amongst other things, this will tell you about the Command Switches: perhaps lack of knowledge in this area is why you're coding your script the way you are.

        I put the above code in pm_1076103.pl and created three *.doc files:

        $ ls -al *.doc -rw-r--r-- 1 ken staff 52 26 Feb 03:20 pm_1076103_1.doc -rw-r--r-- 1 ken staff 52 26 Feb 03:22 pm_1076103_2.doc -rw-r--r-- 1 ken staff 52 26 Feb 03:22 pm_1076103_3.doc $ cat pm_1076103_1.doc Doc 1 Line 1 Doc 1 Line 2 Doc 1 Line 3 Doc 1 Line 4 $ cat pm_1076103_2.doc Doc 2 Line 1 Doc 2 Line 2 Doc 2 Line 3 Doc 2 Line 4 $ cat pm_1076103_3.doc Doc 3 Line 1 Doc 3 Line 2 Doc 3 Line 3 Doc 3 Line 4

        I then ran the script like this:

        $ pm_1076103.pl *.doc

        Here's what the *.doc files now look like:

        $ cat pm_1076103_1.doc Doc 1 Line 1 Doc 1 Line 2 Doc 1 Line 3 VALUE=KEY Doc 1 Line 4 $ cat pm_1076103_2.doc Doc 2 Line 1 Doc 2 Line 2 Doc 2 Line 3 VALUE=KEY Doc 2 Line 4 $ cat pm_1076103_3.doc Doc 3 Line 1 Doc 3 Line 2 Doc 3 Line 3 VALUE=KEY Doc 3 Line 4

        -- Ken

        Hi,
        "..In our server there is no stricts and warning in stalled @INC hence unable to use this in my test script..."
        strict and warnings comes installed with your perl installation. strict since perl 5 and warnings since perl v5.6.0. So if your perl version is newer than the ones i mentioned then you have these pragma installed.
        Just use like so

        use warnings; use strict;
        in your perl scripts.
        Moreso, I wonder why you are using a oneliner perl with a backtick while you can do all that very simply and clearly like so:
        *
        use warnings; use strict; for my $file ( glob("*.pl") ) { open my $fh, '<', $file or die $!; while ( defined( $_ = <$fh> ) ) { print $_; print "adding value=key\n" if $. == 3; } }
        * Update

        If you tell me, I'll forget.
        If you show me, I'll remember.
        if you involve me, I'll understand.
        --- Author unknown to me
        "In our server there is no stricts and warning in stalled @INC hence unable to use this in my test script."

        It's not "stricts", it's "strict". I have no "stricts" either:

        $ perl -Mstricts -e 1 Can't locate stricts.pm in @INC (you may need to install the stricts m +odule) (@INC contains: ...). BEGIN failed--compilation aborted.

        It's not "warning", it's "warnings". I have no "warning" either:

        Can't locate warning.pm in @INC (you may need to install the warning m +odule) (@INC contains: ...). BEGIN failed--compilation aborted.

        Please try these from your command line and report any output:

        perl -Mstrict -e 1
        perl -Mwarnings -e 1

        If you get no output from those, you have both strict and warnings installed. However, if either produces any output, please run this and report all output:

        perl -v

        -- Ken

Re: Problem in executing the perl oneliner within the script
by 2teez (Vicar) on Feb 25, 2014 at 08:39 UTC

    Hi,
    I doubt it if the perl -ni -e 'print; print "adding value=key\n" if $.==3' myfile.txt even run from the CLI without generating a syntax error.
    Simply using the below as a script

    while (defined($_ = <ARGV>)) { print $_; print "adding value=key\n" if $. == 3; }
    could solve this easily.

    Update:
    I got your code wrong. You shouldn't have a syntax error using that from CLI, but as specified from the script you will.

    Secondly, do you just want the line included on 3rd line or at the count of 3 lines? If the former, then the above will do, but if the later, then you might have to change this line: print "adding value=key\n" if $. == 3;

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: Problem in executing the perl oneliner within the script
by Anonymous Monk on Feb 25, 2014 at 08:22 UTC