Ответ 1
То, что вы ищете, $ARGV
. Цитата из perlvar:
$ARGV
Contains the name of the current file when reading from <> .
Итак, ваш однострочный шрифт станет следующим:
perl -ne 'print $ARGV if(/needle/)' haystack.txt
Хотя помните, что он будет печатать один раз для каждого матча. Если вы хотите добавить новую строку в печать, вы можете использовать опцию -l
.
perl -lne 'print $ARGV if(/needle/)' haystack.txt
Если вы хотите, чтобы он печатался только один раз для каждого совпадения, вы можете закрыть дескриптор файла ARGV и перейти к следующему файлу:
perl -lne 'if (/needle/) { print $ARGV; close ARGV }' haystack.txt haystack2.txt
Как указывает Питер Мортенсен, $ARGV
и $ARGV[0]
- две разные переменные. $ARGV[0]
относится к первому элементу массива @ARGV
, тогда как $ARGV
является скаляром, который является совершенно другой переменной.
Вы говорите, что @ARGV
не заполняется при использовании переключателя -p
или -n
, что неверно. Код, который работает беззвучно, выглядит примерно так:
while (@ARGV) {
$ARGV = shift @ARGV; # arguments are removed during runtime
open ARGV, $ARGV or die $!;
while (defined($_ = <ARGV>)) { # long version of: while (<>) {
# your code goes here
} continue { # when using the -p switch
print $_; # it includes a print statement
}
}
Что по существу означает, что использование $ARGV[0]
никогда не покажет реальное имя файла, поскольку оно удаляется до его обращения и помещается в $ARGV
.