Как наилучшим образом передать аргументы в однострочный Perl?
У меня есть файл someFile
, например:
$cat someFile
hdisk1 active
hdisk2 active
Я использую эту оболочку script для проверки:
$cat a.sh
#!/usr/bin/ksh
for d in 1 2
do
grep -q "hdisk$d" someFile && echo "$d : ok"
done
Я пытаюсь преобразовать его в Perl:
$cat b.sh
#!/usr/bin/ksh
export d
for d in 1 2
do
cat someFile | perl -lane 'BEGIN{$d=$ENV{'d'};} print "$d: OK" if /hdisk$d\s+/'
done
Я экспортирую переменную d
в оболочку script и получаю значение с помощью %ENV
в Perl. Есть ли лучший способ передать это значение одному слою Perl?
Ответы
Ответ 1
Вы можете включить рудиментарный аргумент командной строки с помощью переключателя "s". Определяется переменная для каждого аргумента, начинающегося с тире. --
указывает, где начинаются ваши аргументы командной строки.
for d in 1 2 ; do
cat someFile | perl -slane ' print "$someParameter: OK" if /hdisk$someParameter\s+/' -- -someParameter=$d;
done
Смотрите: perlrun
Ответ 2
Иногда разрыв корпуса Perl - хороший трюк для этих однострочных устройств:
for d in 1 2 ; do cat kk2 | perl -lne ' print "'"${d}"': OK" if /hdisk'"${d}"'\s+/';done
Ответ 3
Если у вас возникли проблемы с написанием однострочного изображения, может быть, это немного сложно для одной строки (просто мое мнение). Я согласен с предложением @FM и сделаю все на Perl. Прочтите весь файл, а затем проверьте его:
use strict;
local $/ = '' ; # Read in the whole file
my $file = <> ;
for my $d ( 1 .. 2 )
{
print "$d: OK\n" if $file =~ /hdisk$d\s+/
}
Вы можете сделать это, но это будет длиннее. Конечно, это зависит от размера файла.
Обратите внимание, что все примеры Perl пока распечатывают сообщение для каждого совпадения - можете ли вы быть уверены, что дубликатов нет?
Ответ 4
Передайте его в командной строке, и он будет доступен в @ARGV
:
for d in 1 2
do
perl -lne 'BEGIN {$d=shift} print "$d: OK" if /hdisk$d\s+/' $d someFile
done
Обратите внимание, что оператор shift
в этом контексте удаляет первый элемент @ARGV
, который в этом случае $d
.
Ответ 5
Это выглядит хорошо, но я бы использовал:
for d in $(seq 1 2); do perl -nle 'print "hdisk$ENV{d} OK" if $_ =~ /hdisk$ENV{d}/' someFile; done
Ответ 6
Объединив некоторые из предыдущих предложений и добавив к нему свой собственный сахар, я сделаю так:
perl -se '/hdisk([$d])/ && print "$1: ok\n" for <>' -- -d='[value]' [file]
[значение] может быть числом (т.е. 2), диапазоном (т.е. 2-4), списком разных чисел (т.е. 2 | 3 | 4) (или почти что-либо еще, действительным шаблоном) или даже a bash переменная, содержащая один из таких, например:
d='2-3'
perl -se '/hdisk([$d])/ && print "$1: ok\n" for <>' -- -d=$d someFile
и [файл] - ваше имя файла (то есть someFile
).
Ответ 7
Мое решение немного другое. Я пришел к вашему вопросу с поиском Google в заголовке вашего вопроса, но я пытаюсь выполнить что-то другое. Здесь это на случай, если это поможет кому-то:
FYI, я использовал tcsh в Solaris.
У меня был следующий однострочный:
perl -e 'use POSIX qw(strftime); print strftime("%Y-%m-%d", localtime(time()-3600*24*2));'
который выводит значение:
2013-05-06
Я пытался поместить это в оболочку script, чтобы я мог создать файл с датой в имени файла, из Х числа дней в прошлом. Я пробовал:
set dateVariable=`perl -e 'use POSIX qw(strftime); print strftime("%Y-%m-%d", localtime(time()-3600*24*$numberOfDaysPrior));'`
Но это не сработало из-за замены переменных. Мне пришлось возиться с цитированием, чтобы заставить его правильно интерпретировать его. Я попытался включить всю партию в двойные кавычки, но это сделало команду Perl синтаксически неправильной, поскольку она перепуталась с двойными кавычками в формате даты. Я закончил с:
set dateVariable=`perl -e "use POSIX qw(strftime); print strftime('%Y-%m-%d', localtime(time()-3600*24*$numberOfDaysPrior));"`
Это отлично подойдет для меня, не прибегая к какой-либо причудливой переменной, экспортирующей.
Я понимаю, что это точно не отвечает на ваш конкретный вопрос, но он ответил на заголовок и может помочь кому-то еще!