Sinalizadores de Perl -pe, -pi, -p, -w, -d, -i, -t?

107

Já vi muitas maneiras de executar códigos ou scripts Perl, com sinalizadores diferentes. No entanto, quando tento pesquisar no Google o que significa cada sinalizador, obtenho principalmente resultados para sites Perl genéricos e nenhuma informação específica sobre os sinalizadores ou seu uso é encontrada lá.

Abaixo estão as sinalizações que encontro com mais frequência e não tenho ideia do que significam:

  • perl -pe
  • perl -pi
  • perl -p
  • perl -w
  • perl -d
  • perl -i
  • perl -t

Ficarei muito grato se você me disser o que cada um deles significa e alguns casos de uso para eles, ou pelo menos me dizer uma maneira de descobrir seu significado.

Tudor Constantin
fonte
21
pesquisar por respostas básicas sobre perl geralmente o levará a alguns sites realmente inúteis. sempre verifique a documentação do próprio perl primeiro.
ysth
2
Destacado. Nesse caso, perldoc perlruntem uma lista de todas as opções de linha de comando que o Perl aceita.
Sherm Pendley
1
Problema do Google: o sinal de menos é interpretado pelo Google como significando "excluir este termo". Para evitar esse comportamento, coloque o termo que contém o sinal de menos entre aspas.
Roger Krueger

Respostas:

147

Sim, o Google é notoriamente difícil para procurar sinais de pontuação e, infelizmente, Perl não parecem ser maioritariamente constituído por pontuação :-)

As opções de linha de comando são todas detalhadas em perlrun . (disponível na linha de comando chamando perldoc perlrun)

Analisando as opções brevemente, uma por uma:

-p: coloca um loop de impressão ao redor do seu comando para que ele atue em cada
    linha de entrada padrão. Usado principalmente para que o Perl possa vencer o
    calças fora de moda em termos de poder E simplicidade :-)
-n: Coloca um loop não imprimível em torno de seu comando.
-e: Permite que você forneça o programa como um argumento, em vez
    do que em um arquivo. Você não quer ter que criar um script
    arquivo para cada pequena linha de Perl.
-i: Modifica seu arquivo de entrada no local (fazendo um backup do
    original). Útil para modificar arquivos sem a {cópia,
    excluir original, renomear} processo.
-w: Ativa alguns avisos. Qualquer bom programador Perl usará isso.
-d: é executado no depurador Perl. Para depurar seu código Perl,
    obviamente.
-t: trata certos códigos "contaminados" (duvidosos) como avisos (adequados
    o modo contaminado apresentará erro neste código duvidoso). Usado para carne
    a segurança do Perl, especialmente ao executar código para outros
    usuários, como scripts setuid ou coisas da web.
paxdiablo
fonte
1
Eu não percebi que você se referiu perldoc perlrun. Eu apaguei minha resposta. :-)
Alan Haggai Alavi
4
-wgeralmente deve ser evitado, pois permite avisos para todos os códigos, incluindo módulos CPAN que não foram escritos com os avisos em mente. Os resultados são geralmente muito barulhentos e também inúteis.
Crepúsculo-inativo-
9
-wgeralmente é evitado, mas deve ser substituído por use warningsem seu próprio código.
plusplus de
6
@duskwuff: Em geral, eu concordo, e concordo use warningsem meu próprio código, mas -w tem uma utilidade - ajuda a eliminar módulos CPAN mal escritos. :-)
Sherm Pendley
2
@IanBytchek Argumentos que podem / devem ter um parâmetro adicional não podem estar dentro de uma lista compactada. -ileva uma extensão para o backup. -erecebe um comando perl. Em -0ep você está dizendo ao perl que 'p' é um comando perl ao invés de um argumento. Isso não funcionará bem.
tjd
10

A -pbandeira basicamente executa o script com

while (<>) {
# exec here
}
continue {
    print or die "-p destination: $!\n";
}

-e permite que você passe um script para STDIN

perl -e '$x = "Hello world!\n"; print $x;'

-idireciona o intérprete para que todos os dados passados STDINpelo script em execução sejam executados no local.

-wé o mesmo que use warnings;, mas em um escopo global e não local

-d executa o depurador Perl

Zellio
fonte
2
-wnão é exatamente o mesmo que use warnings, o último tem como escopo o arquivo local
plusplus
plusplus, true, patching answer.
zellio
2
Passar o script como um argumento não é o mesmo que passá-lo para STDIN. -i obtém nomes de arquivos da lista de argumentos, não stdin. Embora STDIN seja frequentemente associado ao terminal de controle e seja herdado do shell que lê stdin e configura a lista de argumentos para perl, eles NÃO são a mesma coisa.
William Pursell
8

Outros mencionaram perlrun. Se você usar B :: Deparse, poderá ver o que significa (para a maioria das coisas):

$ perl -MO=Deparse   -p  -e 1
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

1 é representado por '???', porque é totalmente otimizado.

$ perl -MO=Deparse   -p -i  -e 1
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

-i define $ ^ I, gosto

$ perl -MO=Deparse   -p -i.bak  -e 1
BEGIN { $^I = ".bak"; }
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

Mas lembre-se, <ARGV> usa 2 argumentos abertos, então não tenha nomes de arquivos que comecem com > <ou comecem / terminem com |.

liame
fonte
4

Existe também um sinalizador importante -nque não é mencionado na lista.

-nfunciona da mesma forma -p, mas não imprime $_por padrão. Isso pode ser muito útil na filtragem de arquivos de texto.

Desta forma, Perl pode substituir grep | sedem uma única linha.

Por exemplo:

perl -ne 'print "$1\n" if /Messages read: (\d+)/' <my_input.txt

Irá imprimir todos os valores inteiros encontrados após "Mensagens lidas:" e nada mais.

enferrujado
fonte
Isso pode ser ainda mais simplificado. Não há necessidade de "imprimir" $ 1 \ n "". Você pode apenas usar "imprimir".
devorado elysium
Não, não pode, não print $1é o mesmo que print( print $_).
enferrujado
Pode: echo abc | perl -nw -e "print if (1)"irá imprimir abc. Não há necessidade de $1referência.
Elysium devorado
@devouredelysium: Sim, mas não deseja imprimir a linha inteira, mas apenas o número correspondido pela expressão regular.
Ingo Blechschmidt