2013-05-13 2 views
4

мне часто нужно запускать некоторые Perl остротами для быстрых манипуляций с данными, какPerl линейный режим Oneliner с ARGV

some_command | perl -lne 'print if /abc/' 

Чтение из трубы, мне не нужен цикл вокруг команды ARG имен файлов , Как я могу достичь следующего?

some_command | perl -lne 'print if /$ARGV[0]/' abc 

Это дает ошибку:

Can't open abc: No such file or directory. 

Я понимаю, что '-n' делает

while(<>) {.... } 

вокруг моей программы, и <> принимает арг как имена файлов, но делать следующий раз каждый раз немного непрактично

#/bin/sh 
while read line 
do 
    some_command | perl -lne 'BEGIN{$val=shift @ARGV} print if /$val/' "$line" 
done 

Есть ли лучший способ получить «внутри» аргументы командной строки Perl ONE-LINER, не считая их именами файлов?

+0

Почему так много людей (а не только этот плакат) зацикливаются на «Perl one-liners»? Они великолепны, когда они работают, но они не являются обязательными; многослойные работы тоже. –

+0

@JonathanLeffler Хм .. это не о одной линии против двух линий. Я могу сделать многострочный скрипт с несколькими '-e'. Но речь идет не о том, чтобы делать ненужные файлы со сценариями. Я много раз использую oneliners, просто потому, что они являются быстрым способом делать некоторые мощные вещи непосредственно из командной строки без редактирования файла сценария ... Возможно, для вас это ОК, создайте файл сценария для 2-строчного скрипта - для меня это быстрее напишите его прямо в командной строке ...;) :) – kobame

+0

@Jonathan, я управляю тысячами серверов. Один лайнер, который я могу вставить в ssh, может вставлять в ряд команд, передаваемых по каналам. Я пропускаю несколько журналов, могу быстро и полностью общаться с кем-то в чате и т. Д. И то, что я сделал, более очевидно в истории bash чем двухступенчатый vi/GET --./ mysecretskript. И с одним лайнером меня редко заманивают от моей настоящей задачи. И я редко пытаюсь установить модули Perl на случайный сервер, когда они могут быть не нужны ничем другим. И я редко нахожу, что я построил гигантскую библиотеку никогда-полезных, опять же недокументированных, таинственно названных сценариев. –

ответ

2

Некоторые решения:

perl -e'$p = shift; while (<>) { print if /$p/ }' pat 

perl -e'$p = shift; print grep /$p/, <>' pat # Inefficient. 

perl -ne'BEGIN { $p = shift } print if /$p/' pat 

PAT=pat perl -ne'print if /$ENV{PAT}/' 

Конечно, это могло бы иметь больше смысла, чтобы создать шаблон, который приведен ORing или все модели, а не выполнение той же команды для каждого шаблона.

2

Это зависит от того, что вы думаете, будет в строках вы читали, но вы можете играть с:

#/bin/sh 
while read line 
do 
    some_command | perl -lne "print if /$line/" 
done 

Очевидно, что если $line может содержать косую черту, это не будет летать. Затем, AFAIK, вы застряли с формулировкой блока BEGIN.

+0

Использование двойных кавычек также расширит переменную '$ _' (последний аргумент последней команды bash). '$ _' довольно распространен в моих oneliners.;) Но, в любом случае, спасибо за предложение - хороший момент. :) – kobame

+1

Вам, безусловно, нужно просмотреть код в каждом случае, а использование двойных кавычек вокруг программы в аргументе '-e' обычно более опасно, чем использование одиночных кавычек. Вы должны использовать '\ $' для защиты '$' и т. Д. В этом конкретном контексте он работает без этих осложнений; для чего-то гораздо более сложного, я бы, вероятно, пошел с одинарными кавычками и блоком BEGIN. –

4

Также достаточно короткий:

... | expr=abc perl -lne 'print if /$ENV{expr}/' 

bash Работает в оболочке, но, возможно, не в других оболочках.

+0

Sneaky. Работает с оболочками на основе POSIX (Bourne, Korn, ... - и Bash, как указано), но не с производными оболочки C. Но это нормально; морские раковины должны быть оставлены на морском берегу и не использоваться для сценариев. –

+0

@ JonathanLeffler С тех пор, когда настало время, когда вы работаете в POSIX-оболочке? –

+0

@ AdrianFrühwirth: это сокращенная версия - оболочка Bourne поддерживает обозначение и является основой для оболочки POSIX. Таким образом, это должны быть «раковины на основе Борна», а затем перечислять некоторые варианты ... Я не думал, что меня вызовут. –

Смежные вопросы