Как мне лучше всего передать аргументы в однострочную версию Perl? - PullRequest
20 голосов
/ 23 июля 2010

У меня есть файл, someFile, например:

$cat someFile
hdisk1 active
hdisk2 active

Я использую этот скрипт для проверки:

$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 в сценарии оболочки и получаю значение, используя %ENV в Perl. Есть ли лучший способ передачи этого значения в однострочник Perl?

Ответы [ 7 ]

29 голосов
/ 24 июля 2010

Вы можете включить элементарный аргумент командной строки с переключателем "s".Переменная определяется для каждого аргумента, начинающегося с тире.-- указывает, где начинаются аргументы командной строки.

for d in 1 2 ; do 
  cat someFile | perl -slane ' print "$someParameter: OK" if /hdisk$someParameter\s+/' -- -someParameter=$d; 
done

См .: perlrun

3 голосов
/ 11 февраля 2014

Иногда ломка оболочки Perl является хорошим трюком для этих однострочников:

for d in 1 2 ; do cat kk2 | perl -lne ' print "'"${d}"': OK" if /hdisk'"${d}"'\s+/';done
2 голосов
/ 24 июля 2010

Если у вас проблемы с написанием однострочного текста, возможно, для одной строки это немного сложно (только мое мнение).Я бы согласился с предложением @ 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 будут печатать сообщение для каждого совпадения - можете ли вы быть уверены, что дубликатов нет?

2 голосов
/ 24 июля 2010

Передайте его в командной строке, и оно будет доступно в @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.

1 голос
/ 24 июля 2010

Объединив некоторые из предыдущих предложений и добавив в него свой собственный сахар, я бы сделал это следующим образом:

perl -se '/hdisk([$d])/ && print "$1: ok\n" for <>' -- -d='[value]' [file]

[значение] может быть числом (т. Е. 2), диапазоном (т. Е. 2-4), списком различных чисел (т. Е. 2 ​​| 3 | 4) (или почти любым другим, это действительный шаблон) или даже переменная bash, содержащая один из них, например:

d='2-3'
perl -se '/hdisk([$d])/ && print "$1: ok\n" for <>' -- -d=$d someFile 

и [file] - ваше имя файла (то есть someFile).

0 голосов
/ 08 мая 2013

Мое решение немного отличается. Я пришел к вашему вопросу с помощью поиска Google в заголовке вашего вопроса, но я пытаюсь выполнить что-то другое. Вот в случае, если это кому-то поможет:

К вашему сведению, я использовал tcsh на Solaris.

У меня был следующий однострочный:

perl -e 'use POSIX qw(strftime); print strftime("%Y-%m-%d", localtime(time()-3600*24*2));'

который выводит значение:

2013-05-06

Я пытался поместить это в сценарий оболочки, чтобы я мог создать файл с датой в имени файла, из X числа дней в прошлом. Я попробовал:

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));"`

Это прекрасно сработало для меня, не прибегая к каким-либо необычным экспортам переменных.

Я понимаю, что это не совсем отвечает на ваш конкретный вопрос, но он ответил на заголовок и может помочь кому-то еще!

0 голосов
/ 24 июля 2010

Это выглядит хорошо, но я бы использовал:

for d in $(seq 1 2); do perl -nle 'print "hdisk$ENV{d} OK" if $_ =~ /hdisk$ENV{d}/' someFile; done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...