То, что вы ищете, это $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
.