in reply to Differentiating STDIN from arguments when using -n ?

You have to consume the argument in @ARGV before the implicit loop starts. What's more, you must make sure the argument is consumed only once. Hence, most elegant solution: do it in a BEGIN block.
echo stuff | perl -ne 'BEGIN{ $x=shift @ARGV; } print "x=$x\n"' myarg
(untested)

Is this like what you had in mind?

Replies are listed 'Best First'.
Re^2: Differentiating STDIN from arguments when using -n ?
by johngg (Canon) on Sep 15, 2007 at 11:44 UTC
    I tried this but somehow $x seems to become undef after the first time through the implicit loop.

    $ cat gibberish This is a couple of lines of crud $ cat gibberish | perl -Mstrict -Mwarnings -ne ' > my $x; > BEGIN {$x = shift @ARGV; print qq{BEGIN - $x\n}} > print qq{x = $x\n$_};' myarg BEGIN - myarg x = myarg This is a couple Use of uninitialized value in concatenation (.) or string at -e line 4 +, <> line 2. x = of lines of crud $

    I wonder what is causing this.

    Cheers,

    JohnGG

      Don't declare the $x — it's just a one-liner. Perl wraps a while(<>) { ... } loop around the code you put there (really!), so it's a new $x for every line in the file.

      See for yourself:

      perl -n -MO=Deparse -e 'my $x' foo
      produces:
      LINE: while (defined($_ = <ARGV>)) { my $x; } -e syntax OK
Re^2: Differentiating STDIN from arguments when using -n ?
by rduke15 (Beadle) on Sep 15, 2007 at 12:28 UTC

    Thanks a lot. Indeed, with the BEGIN block, it now works.

    In case someone is curious, I needed it in a shell script for a convoluted situation: to be able to un-mount a disk cleanly, I needed a smart sort on the mounted partitions of the disk.

    # $dest was set to "sdb" through a shell argument mounted_disks=$(mount | perl -nae 'BEGIN{$d=shift}; push @m, $F[2] if +m{/dev/$d}; END{print join(" ", sort {length($b)<=>length($a)} @m)}' +$dest) umount -l $mounted_disks

    Thanks to Perl and the Perl Monks, it works.

      You don't really need a loop for that, you could do it like this:

      mounted_disks=$(mount | perl -le'$d = shift; print join " ", sort { le +ngth( $b ) <=> length( $a ) } map m{/dev/$d} ? (split)[2] : (), <>' $ +dest)

      Or even move the mount command into the perl code:

      mounted_disks=$(perl -le'$d = shift; print join " ", sort { length( $b + ) <=> length( $a ) } map m{/dev/$d} ? (split)[2] : (), qx(mount)' $d +est)
        Cool alternative, even if it took me a moment to understand... Thanks.