Adam o Automador

Um dos primeiros comandos Linux que muitos administradores de sistemas aprendem é o grep. Esta venerável ferramenta existe há décadas e é crucial para qualquer administrador de ferramentas. O núcleo do grep é simplesmente a capacidade de procurar texto simples por um padrão RegEx. O grep pode pesquisar ficheiros num determinado directório ou entradas em fluxo contínuo para obter correspondências. Sabia que o PowerShell tem grep? Bem…quase.

PowerShell, sendo uma linguagem, é mais do que apenas um binário de propósito único. Portanto, que capacidades incorporadas existem para procurar texto simples usando padrões RegEx muito semelhantes aos do grep? Neste artigo exploramos as inúmeras formas de procurar texto em ficheiros usando PowerShell.

Explorando a Cmdlet Select-String

Select-String (o nosso grep PowerShell) funciona em linhas de texto e por defeito procura a primeira correspondência em cada linha e depois mostra o nome do ficheiro, número de linha, e o texto dentro da linha correspondente. Adicionalmente, Select-String pode trabalhar com diferentes codificações de ficheiro, tais como texto Unicode, utilizando a marca de ordem de byte (BOM) para determinar o formato de codificação. Se a lista técnica estiver em falta, Select-String assumirá que é um ficheiro UTF8.

Parâmetros de Select-String

  • AllMatches – Normalmente, Select-String apenas procurará a primeira correspondência em cada linha, usando este parâmetro o cmdlet procurará mais do que uma correspondência. Um único objecto MatchInfo ainda será emitido para cada linha, mas conterá todas as correspondências encontradas.
  • CaseSensitive – As correspondências não são sensíveis a maiúsculas/minúsculas por defeito, isto força o cmdlet a procurar correspondências que correspondam exactamente ao padrão de entrada.
  • Context – Um parâmetro muito útil, pois pode definir o número de linhas antes e depois da correspondência que será exibida. Adicionar este parâmetro modifica a propriedade emitida MatchInfo objecto para incluir um novo Context propriedade que contém as linhas especificadas.

eep, tendo em mente que se canalizar a saída de Select-String para outro Select-String chamada, o contexto não estará disponível uma vez que só está a pesquisar no único resultado MatchInfoline propriedade.

  • Culture – Usado com o parâmetro SimpleMatch, isto especifica uma cultura a ser correspondida com o padrão especificado. Isto inclui opções tais como en-USes, ou fr-FR como exemplos. Algumas outras opções úteis são as Ordinal e Invariant opções. Ordinal é para comparações binárias não linguísticas e Invariant é para comparações independentes da cultura.

Este parâmetro foi introduzido no PowerShell 7 e não está disponível para versões anteriores. Tenha também em mente que isto irá utilizar a cultura actual do sistema, por defeito, que pode ser encontrada usando Get-Culture.

  • Encoding – Especifique a codificação do ficheiro alvo a pesquisar, que por defeito é utf8NoBOM.
    • ascii: Utiliza a codificação para o conjunto de caracteres ASCII (7-bit).
    • bigendianunicode: Codifica no formato UTF-16 utilizando a ordem de byte big-endian.
    • oem: Utiliza a codificação padrão para MS-DOS e programas de consola.
    • unicode: Codifica no formato UTF-16 utilizando a ordem de byte little-endian.
    • utf7: Codificações no formato UTF-7.
    • utf8: Codificações no formato UTF-8.
    • utf8BOM: Códigos no formato UTF-8 com Marca de Ordem de Byte (BOM)
    • utf8NoBOM: Codificações no formato UTF-8 sem Marca de Ordem de Byte (BOM)
    • utf32: Codificações no formato UTF-32.

    Iniciar com PowerShell Core 6.2, o parâmetro Encoding também aceita IDs numéricos de páginas de código registadas tais como 1251 ou nomes de string tais como windows-1251.

Iniciar com PowerShell Core 6.2, o parâmetro Encoding também aceita IDs numéricos de páginas de código registadas tais como 1251 ou nomes de strings tais como windows-1251.

  • Exclude – Trabalhando com o parâmetro Path, excluir itens específicos utilizando um padrão, tais como *.txt.
  • Include – Tal como o parâmetro ExcludeInclude incluirá apenas os itens especificados utilizando um padrão, tal como *.log.
  • List – Só devolverá a primeira instância de texto correspondente de cada ficheiro de entrada. Esta destina-se a ser uma forma rápida e eficiente de recuperar uma listagem de ficheiros com conteúdo correspondente.
  • LiteralPath – Isto diz Select-String para usar os valores como entrada, em vez de interpretar valores como * como um wildcard. Se o caminho incluir caracteres de fuga, anexá-los entre aspas simples para não fazer interpretação.
  • NoEmphasis – Em vez de destacar a string sobre a qual o padrão é correspondido, desactivar o destaque de correspondências. Por defeito, a ênfase usa cores negativas baseadas nas cores do texto de fundo.
  • NotMatch – Procure texto que não corresponda ao padrão especificado.
  • Path – Especifique o caminho para os ficheiros a pesquisar. Os wildcards são permitidos, mas não se pode especificar apenas um directório. O padrão é o directório local.
  • Pattern – O padrão para pesquisar o conteúdo de entrada ou ficheiros com base em RegEx.
  • SimpleMatch – Use uma simples correspondência em vez de expressões regulares. Uma vez que RegEx não é utilizado, o MatchInfo objecto não tem quaisquer valores no Matches propriedade.
  • Raw – Produzir as cordas correspondentes, sem um objecto MatchInfo. Este é o comportamento mais semelhante a grep e não a natureza mais orientada para objectos do PowerShell.
  • Quiet – Apenas retornar um $true ou $false se o padrão for encontrado.

Using PowerShell Grep err… Select-String

Off course knowing how the parameters and options of a cmdlet work is not quite the same as using it in a production environment. Vamos mergulhar em exemplos e ver como podemos aproveitar Select-String para facilitar a procura de correspondência de texto.

Existem três maneiras que podemos utilizar Select-String para encontrar correspondência.

  • capítulo em texto citado para o Select-String cmdlet, ou seja, fluxo no texto.
  • Utilizando texto armazenado numa variável, passe a variável para o parâmetro InputObject.
  • Utilizar o parâmetro Path para especificar ficheiros para procurar o texto.

Os ficheiros que estamos a utilizar para testar este conteúdo são de conteúdo gerado aleatoriamente, mas do mesmo tipo que é frequentemente encontrado nos sistemas de produção.

Melhança Simples em Ficheiros

A partir de um exemplo muito simples, vamos procurar Joe num punhado de ficheiros CSV.

Select-String -Path "Users\*.csv" -Pattern "Joe"
Demonstrando uma simples correspondência de padrão Select-String.
Demonstruindo uma simples correspondência de padrão Select-String.

Como se pode ver, isto é bastante simples, vemos como Joe é realçado na linha com o resto dos dados. Mas que dados estão de facto a ser devolvidos aqui? Vejamos todas as propriedades de uma correspondência retornada.

Select-String -Path "Users\*.csv" -Pattern "Joe" | Select-Object * -First 1
Mostrando as propriedades retornadas de uma correspondência de Selecciona-Corda.
Showing the return properties from a Select-String match.

Temos aqui um par de propriedades que são úteis. Nomeadamente o linepathpattern, e matches. A maior parte do que queremos saber está em matches property.

Select-String -Path "Users\*.csv" -Pattern "Joe" | Select-Object -ExpandProperty Matches -First 1
Enumerar a propriedade Fósforos e os dados disponíveis.
Enumerar a propriedade Fósforos e os dados disponíveis.

Aqui pode ver como, apesar de termos usado uma expressão simples, esta continua a ser uma expressão RegEx e os detalhes subsequentes disponíveis.

E se procurarmos vários valores diferentes usando padrões separados por vírgulas? Isto é útil, uma vez que na realidade define três padrões diferentes e não um valor RegEx complexo.

Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry"
Retornar múltiplas combinações a partir de uma pesquisa Select-String.
Returning multiple matches from a Select-String search.

P>Pode ver como este é o caso, se seleccionarmos apenas o filenamepattern, e line a partir da nossa pesquisa.

Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry" | Select-Object FileName, Pattern, Line
Filtrar os resultados de uma combinação múltipla Select-String.
Filtrar os resultados de uma combinação múltipla Select-String.

Mais Complexo de Correspondência RegEx

Agora que demonstrámos alguns dos métodos de correspondência mais simples, que tal utilizar mais RegEx para realmente procurar padrões mais úteis? Os três exemplos aqui estão à procura de Endereços de Email, Endereços IP, e Números de Segurança Social (SSNs). Os padrões aqui utilizados não são a única forma de construir uma pesquisa RegEx, e pode haver formas mais fáceis. PowerShell Grep (Select-String) é um cmdlet bastante avançado.

P>Vejamos se os emails estão contidos nos nossos ficheiros. Usando uma correspondência RegEx algo complexa, como mostrado abaixo, demonstrará encontrar essas correspondências.

Select-String -Path "Users\*.csv" -Pattern '\\b+\.{2,4}\b' | Select-Object -First 10
Demonstrando usando RegEx para corresponder dados.
Demonstruir usando RegEx para combinar dados.

Obviamente, poderia ser mais preocupante se houvesse SSNs incluídos num ficheiro. Uma correspondência muito simples para isto seria a seguinte.

Select-String -Path "Users\*.csv" -Pattern '\d\d\d-\d\d-\d\d\d\d' | Select-Object -First 10
Demonstrando uma pesquisa simples no SSN RegEx.
Demonstruindo uma pesquisa simples no SSN RegEx.

Finalmente, e se quiséssemos pesquisar alguns endereços IP no nosso ficheiro? Usando outra expressão RegEx para procurar esse padrão, faz um trabalho rápido.

Select-String -Path "Users\*.csv" -Pattern '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' | Select-Object -First 10
Demonstrando uma simples pesquisa RegEx de endereços IP.
Demonstruir uma pesquisa RegEx de endereço IP simples.

Uma advertência sobre este RegEx. Tecnicamente, isto irá corresponder a valores até 999.999.999.999 que é um IP inválido. É possível construir expressões RegEx mais precisas que ficarão mais longas, mas é uma troca dependendo do que se pretende fazer.

Procura com Contexto

Contexto é muito útil na resolução de problemas, ajuda a explicar o que está a acontecer antes e depois de um evento ocorrer. Por exemplo, vamos procurar num registo Apache e encontrar isto suspendedpage.cgi text.

Select-String -Path "Web\*.txt" -Pattern "suspendedpage.cgi" -Context 1 | Select-Object -First 1
Procura de uma linha num registo Apache.
Procura de uma linha num log Apache.

The > simples indica a linha correspondente, e há uma linha antes da partida e depois da partida. Neste exemplo, isto poderia dizer-nos que o bot do Google procurava robots.txt e infelizmente recebeu um suspendedpage.cgi resultado em vez disso. A seguir, foi tentar a página inicial e talvez recebeu o mesmo erro.

O que é que está exactamente contido no context propriedade então como emitida pelo objecto MatchInfo? Se expandirmos essa propriedade, pode ver que existe PreContent e PostContent. Isto significa que pode manipular isto mais abaixo se necessário.

Select-String -Path "Web\*.txt" -Pattern "suspendedpage.cgi" -Context 1 | Select-Object -ExpandProperty Context -First 1 | Format-List
Demonstrando a propriedade Contexto.
Demonstrando a propriedade Contexto.

Outros exemplos de pesquisa através de ficheiros de registo estão em artigos tais como Making Sense of the Microsoft DNS Debug Log que demonstra usando Select-String para procurar através de um registo de depuração DNS. O grep PowerShell é forte nesse post.

Conclusion

Grep é uma ferramenta incrivelmente útil no mundo Linux, e Select-String oferece muito da mesma funcionalidade no mundo PowerShell. Adicionar na natureza orientada a objectos do PowerShell serve apenas para aumentar a utilidade e utilidade que o cmdlet oferece.

Para muitos administradores de sistemas, ser capaz de pesquisar rápida e eficientemente ficheiros de registo em vários tipos, juntamente com a compreensão do contexto, é uma capacidade incrivelmente importante e necessária. PowerShell Select-String torna isto fácil de fazer e poupa incontáveis horas de resolução de problemas!

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *