ventajas tutorial strawberry logo historia desventajas perl

strawberry - perl tutorial



Perl: ¿Cómo obtener el nombre de archivo cuando se usa<> construir? (3)

Perl ofrece esta característica muy agradable:

while ( <> ) { # do something }

... que permite que el script se use como script.pl <filename> así como cat <filename> | script.pl cat <filename> | script.pl .

Ahora, ¿hay una manera de determinar si el script ha sido llamado de la forma anterior, y si es así, cuál fue el nombre del archivo?

Sé que lo supe una vez, y sé que incluso utilicé el constructo, pero no puedo recordar dónde / cómo. Y resultó muy difícil buscar en la red para esto ("perl stdin filename"? No ...).

¿Ayuda por favor?


La sección Operadores de E / S de perlop es muy informativa sobre esto.

Esencialmente, la primera vez que se ejecuta <> , - se agrega a @ARGV si comenzó vacío. Apertura - tiene el efecto de clonar el identificador del archivo STDIN y la variable $ARGV se establece en el elemento actual de @ARGV medida que se procesa.

Aquí está el clip completo.

El identificador de archivo nulo "<>" es especial: puede usarse para emular el comportamiento de sed y awk, y cualquier otro programa de filtro de Unix que tome una lista de nombres de archivos, haciendo lo mismo con cada línea de entrada de todos ellos. La entrada de "<>" proviene de la entrada estándar o de cada archivo listado en la línea de comando. Así es como funciona: la primera vez que se evalúa "<>", se comprueba la matriz @ARGV y, si está vacía, $ ARGV [0] se establece en "-", que cuando se abre le da una entrada estándar. La matriz @ARGV se procesa como una lista de nombres de archivos. El lazo

while (<>) { ... # code for each line }

es equivalente al siguiente pseudo código similar a Perl:

unshift(@ARGV, ''-'') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }

excepto que no es tan engorroso decirlo, y realmente funcionará. Realmente cambia la matriz @ARGV y coloca el nombre de archivo actual en la variable $ ARGV. También utiliza filehandle ARGV internamente. "<>" es solo un sinónimo de "<ARGV>", que es mágico. (El pseudo código anterior no funciona porque trata "<ARGV>" como no mágico.)


La variable $ARGV contiene el archivo actual que se está procesando.

$ echo hello1 > file1 $ echo hello2 > file2 $ echo hello3 > file3 $ perl -e ''while(<>){s/^/$ARGV:/; print;}'' file* file1:hello1 file2:hello2 file3:hello3


Si le interesa saber cuándo <> cambia a un nuevo archivo (por ejemplo, en mi caso, quería registrar el nuevo nombre de archivo y número de línea), entonces la documentación de la función eof () ofrece un truco:

# reset line numbering on each input file while (<>) { next if /^/s*#/; # skip comments print "$./t$_"; } continue { close ARGV if eof; # Not eof()! }