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 objectoMatchInfo
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 emitidaMatchInfo
objecto para incluir um novoContext
propriedade que contém as linhas especificadas.
eep, tendo em mente que se canalizar a saída de
Select-String
para outroSelect-String
chamada, o contexto não estará disponível uma vez que só está a pesquisar no único resultadoMatchInfo
line
propriedade.
-
Culture
– Usado com o parâmetroSimpleMatch
, isto especifica uma cultura a ser correspondida com o padrão especificado. Isto inclui opções tais comoen-US
es
, oufr-FR
como exemplos. Algumas outras opções úteis são asOrdinal
eInvariant
opções.Ordinal
é para comparações binárias não linguísticas eInvariant
é 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 como1251
ou nomes de string tais comowindows-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 como1251
ou nomes de strings tais comowindows-1251
.
-
Exclude
– Trabalhando com o parâmetroPath
, excluir itens específicos utilizando um padrão, tais como*.txt
. -
Include
– Tal como o parâmetroExclude
Include
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 dizSelect-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, oMatchInfo
objecto não tem quaisquer valores noMatches
propriedade. -
Raw
– Produzir as cordas correspondentes, sem um objectoMatchInfo
. Este é o comportamento mais semelhante agrep
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"
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
Temos aqui um par de propriedades que são úteis. Nomeadamente o line
path
pattern
, 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
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"
P>Pode ver como este é o caso, se seleccionarmos apenas o filename
pattern
, e line
a partir da nossa pesquisa.
Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry" | Select-Object FileName, Pattern, Line
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
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
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
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
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
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!