Links de salto
-
Correspondência Regex para substituir grep
-
Imprimindo campos para substituir awk
-
Pesquise e substitua para substituir Sed
-
Classificando para substituir classificação
-
Removendo duplicatas para substituir uniq
-
Substituindo tr por substituição de caracteres
Embora outras linguagens de script tenham ganhado popularidade, Perl continua sendo uma escolha popular devido às suas robustas capacidades de processamento de texto. É fácil criar “one-liners” ou scripts muito curtos, que podem até substituir utilitários Unix independentes. Aqui estão algumas ferramentas que você pode criar diretamente na linha de comando.
Correspondência Regex para substituir grep
grep é uma das ferramentas mais úteis do Linux para examinar a saída. Ele pesquisa texto usando expressões regulares, uma linguagem precisa que permite especificar correspondências até o nível do caractere. Perl é conhecido por suas habilidades de correspondência de expressões regulares, tanto que muitos outros utilitários e linguagens de programação anunciam expressões regulares “compatíveis com Perl”.
É fácil configurar uma versão Perl de uma linha do grep:
perl -ne'print if /PATTERN/'
Vamos examinar isso. A opção -n diz ao interpretador Perl para assumir que este loop já existe em torno do programa:
while (<>) {
do_something
}
O -n significa que o Perl receberá qualquer entrada proveniente da entrada padrão ou de um nome de arquivo. Os símbolos maior que e menor queé o operador filehandle do Perl. Perl percorrerá cada linha do arquivo e executará as operações que você especificou no bloco. O padrão entre as duas barras será a expressão regular que você está tentando corresponder. Veja opágina perlrun na documentação Perlpara mais informações sobre as opções de linha de comando do Perl.
O -e dirá ao Perl para não procurar um arquivo fonte Perl, como um que termine com .pl. Isto é o que torna possíveis as one-liners do Perl. Juntando tudo isso, podemos construir um pequeno substituto para o programa grep. Vamos ver como funciona.
Suponha que você queira encontrar shells em execução no sistema. Como os shells do Linux normalmente terminam em sh, podemos procurar esse padrão. Para obter a lista de todos os processos em execução, você pode usar o comando “ps aux” para obter a lista de processos em execução para todos os usuários e redirecionar a saída para o seu one-liner com o “|” ou caractere de barra vertical.
Podemos começar apenas combinando o padrão “sh”:
ps aux | perl -ne 'print if /sh/'
Isto imprimirá qualquer linha que corresponda ao padrão “sh” na saída do programa ps. Também podemos ser mais específicos com quantificadores de caracteres. Para corresponder ao “s” seguido por um h:
ps aux | perl -ne 'print if /.sh/'
Também podemos especificar qualquer caractere único que contenha “sh”. Isso irá corresponder a coisas como “bash” ou “zsh”
ps aux | perl -ne 'print if /.*sh/'
Certifique-se de que qualquer código Perl real em uma linha única Perl esteja entre aspas simples, para que o shell não os interprete em vez de Perl. Caso contrário, você receberá uma mensagem de erro.
Como muitos nomes de shell terminam em “sh”, podemos procurar qualquer coisa que contenha “sh” no final de uma palavra com a classe de caracteres “b”:
ps aux | perl -ne 'print if /.*shb/'
Isso não funcionará apenas com saída redirecionada, mas também em arquivos
perl -ne 'print if /.*sh/' example.txt
Isso imprimirá qualquer linha contendo “sh” no arquivo example.txt.
Você também pode substituir o grep inverso, ou grep -i, usando o comando “unless” em Perl:
perl -ne 'print unless /sh/'
Imprimindo campos para substituir awk
awk é outro utilitário Linux venerável que é útil para trabalhar com dados organizados em colunas, como processos ou bancos de dados simples. Um one-liner Perl também pode passar por esse código rapidamente.
Suponha que quiséssemos mostrar o nome do usuário e o programa que o usuário estava executando a partir do comando ps aux, escreveríamos algo assim:
ps aux | perl -ane 'print "$F[0] $F[10]n"'
O que o código Perl faz é assumir o clássico loop “while ()” em torno do programa, mas também divide a entrada em campos. Os campos são armazenados em uma matriz chamada “@F”, onde uma matriz é identificada por um símbolo “arroba” (@). Para obter os valores da matriz, você adiciona um cifrão ao nome e o número do campo como um número, começando em 0 para o primeiro elemento. Perl é criticado pela suposta confusão de usar “sigilos” como o cifrão para identificar variáveis, mas é fácil de entender quando você conhece essa convenção.
Além disso, preste atenção às citações. Esta expressão Perl com as variáveis precisará estar entre aspas duplas dentro da expressão de aspas simples para garantir que o intérprete Perl a veja.
O exemplo acima irá imprimir a primeira coluna, $F[0]que é o nome do usuário, enquanto $F[10] recupera o nome do caminho do executável associado a esse processo. É assim que a versão Linux do ps relata sua saída. Se você estiver usando um sistema BSD, talvez seja necessário ajustá-lo. Uma linha semelhante funcionaria com qualquer outro programa usando dados organizados dessa maneira.
Você pode usar a opção -F para especificar um padrão para dividir as linhas. Para saída separada por dois pontos, você usaria algo como:
perl -F '/:/'
Pesquise e substitua para substituir Sed
Você pode ter executado uma operação de pesquisa e substituição usando a construção s/old/new/ no Vim ou na linha de comando usando o programa sed. Como a função de pesquisa e substituição de expressões regulares do Perl parece, ahem, “inspirada” neste utilitário clássico do Unix, é fácil traduzir para um liner Perl:
perl -pe "s/old/new/"
Isso funcionará tanto com a entrada canalizada para ele quanto na própria linha de comando. Espero que, se Randal Schwartz ler isso, ele não me dê o prêmio de “Uso inútil de gato”. Por exemplo, para substituir “cachorro” por “gato”
perl -pe "s/dog/cat"
Você pode experimentar algo como “Gosto de acariciar meu cachorro”.
A palavra “cachorro” será alterada para “gato”.
Se você tentar fazer isso em uma linha como “O hálito do meu cachorro cheira a comida de cachorro”, com mais de uma instância do padrão que deseja substituir na linha, poderá notar que apenas a primeira ocorrência é substituída:
My cat's breath smells like dog food.
Se o hálito do seu gato realmente cheirar a comida de cachorro, isso seria suficiente. Você também pode substituir todas as instâncias anexando o operador “s/antigo/novo” original por “g” para “global.
Vamos garantir que o hálito do seu gato cheire a comida de gato:
perl -pe "s/dog/cat/g"
Agora, todas as instâncias do padrão serão substituídas quando aparecerem na linha.
Classificando para substituir classificação
Você pode usar a classificação para classificar a entrada padrão em ordem alfabética. Isso também é fácil de fazer com uma linha
perl -e "print sort <>"
Isso dirá ao Perl para classificar a entrada padrão, que novamente inclui qualquer arquivo especificado na linha de comando, ou canalizado de outro comando, e classificar a saída em ordem alfabética, ou melhor, de acordo com a configuração de “localidade” do seu sistema. No meu caso, é C.UTF-8. Se o seu sistema estiver configurado para usar um idioma diferente, as linhas poderão ser classificadas de forma diferente. No meu sistema, as linhas com letras maiúsculas parecem ser classificadas primeiro.
Removendo duplicatas para substituir uniq
uniq é usado em listas junto com sort para remover entradas duplicadas. Você pode replicar a funcionalidade com esta linha:
perl -ne 'print if $_ ne $prev; $prev = $_'
Isto irá comparar a linha atual com a anterior e imprimi-la se forem desiguais. A variável “$_” é um atalho para a linha de entrada atual. Embora esta linha demonstre alguns conceitos de Perl, eu provavelmente me limitaria ao uniq na prática, já que ele tem apenas quatro caracteres.
Você pode até combinar one-liners com tubos na carcaça. Aqui está um exemplo para imprimir itens exclusivos gerados por uma linha que seleciona campos da saída mencionada anteriormente:
ps aux | perl -ane 'print "$F[0]n"' | perl -ne 'print if $_ ne $prev; $prev = $_'
Substituindo tr por substituição de caracteres
Embora você tenha visto o operador de pesquisa e substituição anterior trabalhando em expressões regulares, o comando tr no Linux funciona em caracteres individuais e classes de caracteres. Suponha que você queira colocar um arquivo em letras maiúsculas, para que pareça que você está constantemente gritando, você usaria esta linha para substituir tr:
T
perl -pe 'tr/a-z/A-Z/'
Isso substituirá todos os caracteres minúsculos de a a z por sua contraparte maiúscula.
Essas frases simples devem lhe dar uma ideia do poder de processamento de texto do Perl e mostrar por que a linguagem ainda tem um pouco de vida. Você pode fazer muita coisa com um pouco de código em Perl.