Pesquisa de padrões com Grep em Java

Pesquisa de padrões com Grep em Java

1. Visão geral

Neste tutorial - aprenderemos comosearch for a pattern in a given file/s - usando Java e bibliotecas de terceiros, comoUnix4JeGrep4J.

2. fundo

O Unix tem um comando poderoso chamadogrep - que significa “global regular expression print“. Ele procura o padrão ou uma expressão regular em um determinado conjunto de arquivos.

Pode-se usar zero ou mais opções junto com o comando grep para enriquecer o resultado da pesquisa, que examinaremos em detalhes na próxima seção.

Se você estiver usando o Windows, pode instalar o bash conforme mencionado na postagemhere.

3. com biblioteca unix4j

Primeiro, vamos ver como usar a biblioteca Unix4J para receber um padrão em um arquivo.

No exemplo a seguir - veremos como traduzir os comandos grep do Unix em Java.

3.1. Configuração de compilação

Adicione a seguinte dependência ao seupom.xml oubuild.gradle:


    org.unix4j
    unix4j-command
    0.4

3.2. Exemplo com Grep

Exemplo de grep no Unix:

grep "NINETEEN" dictionary.txt

O equivalente em Java é:

@Test
public void whenGrepWithSimpleString_thenCorrect() {
    int expectedLineCount = 4;
    File file = new File("dictionary.txt");
    List lines = Unix4j.grep("NINETEEN", file).toLineList();

    assertEquals(expectedLineCount, lines.size());
}

Outro exemplo é onde podemos usar a pesquisa inversa de texto em um arquivo. Esta é a versão Unix do mesmo:

grep -v "NINETEEN" dictionary.txt

Esta é a versão Java do comando acima:

@Test
public void whenInverseGrepWithSimpleString_thenCorrect() {
    int expectedLineCount = 178687;
    File file = new File("dictionary.txt");
    List lines
      = Unix4j.grep(Grep.Options.v, "NINETEEN", file). toLineList();

    assertEquals(expectedLineCount, lines.size());
}

Vamos ver como podemos usar a expressão regular para procurar um padrão em um arquivo. Esta é a versão Unix para contar todo o padrão de expressão regular encontrado em todo o arquivo:

grep -c ".*?NINE.*?" dictionary.txt

Esta é a versão Java do comando acima:

@Test
public void whenGrepWithRegex_thenCorrect() {
    int expectedLineCount = 151;
    File file = new File("dictionary.txt");
    String patternCount = Unix4j.grep(Grep.Options.c, ".*?NINE.*?", file).
                          cut(CutOption.fields, ":", 1).toStringResult();

    assertEquals(expectedLineCount, patternCount);
}

4. Com Grep4J

A seguir, vamos ver como usar a biblioteca Grep4J para fazer a grep de um padrão em um arquivo que reside localmente ou em algum lugar remoto.

No exemplo a seguir - veremos como traduzir os comandos grep do Unix em Java.

4.1. Configuração de compilação

Adicione a seguinte dependência ao seupom.xml oubuild.gradle:


    com.googlecode.grep4j
    grep4j
    1.8.7

4.2. Exemplos Grep

Exemplo de grep em Java, ou seja, Equivalente a:

grep "NINETEEN" dictionary.txt

Esta é a versão Java do comando:

@Test
public void givenLocalFile_whenGrepWithSimpleString_thenCorrect() {
    int expectedLineCount = 4;
    Profile localProfile = ProfileBuilder.newBuilder().
                           name("dictionary.txt").filePath(".").
                           onLocalhost().build();
    GrepResults results
      = Grep4j.grep(Grep4j.constantExpression("NINETEEN"), localProfile);

    assertEquals(expectedLineCount, results.totalLines());
}

Outro exemplo é onde podemos usar a pesquisa inversa de texto em um arquivo. Esta é a versão Unix do mesmo:

grep -v "NINETEEN" dictionary.txt

E aqui está a versão Java:

@Test
public void givenRemoteFile_whenInverseGrepWithSimpleString_thenCorrect() {
    int expectedLineCount = 178687;
    Profile remoteProfile = ProfileBuilder.newBuilder().
                            name("dictionary.txt").filePath(".").
                            filePath("/tmp/dictionary.txt").
                            onRemotehost("172.168.192.1").
                            credentials("user", "pass").build();
    GrepResults results = Grep4j.grep(
      Grep4j.constantExpression("NINETEEN"), remoteProfile, Option.invertMatch());

    assertEquals(expectedLineCount, results.totalLines());
}

Vamos ver como podemos usar a expressão regular para procurar um padrão em um arquivo. Esta é a versão Unix para contar todo o padrão de expressão regular encontrado em todo o arquivo:

grep -c ".*?NINE.*?" dictionary.txt

Esta é a versão Java:

@Test
public void givenLocalFile_whenGrepWithRegex_thenCorrect() {
    int expectedLineCount = 151;
    Profile localProfile = ProfileBuilder.newBuilder().
                           name("dictionary.txt").filePath(".").
                           onLocalhost().build();
    GrepResults results = Grep4j.grep(
      Grep4j.regularExpression(".*?NINE.*?"), localProfile, Option.countMatches());

    assertEquals(expectedLineCount, results.totalLines());
}

5. Conclusão

Neste tutorial rápido, ilustramos a busca por um padrão em um determinado arquivo / s usandoGrep4jeUnix4J.

A implementação desses exemplos pode ser encontrada emthe GitHub project - este é um projeto baseado em Maven, portanto, deve ser fácil de importar e executar como está.

Finalmente, você pode fazer naturalmente alguns dos fundamentos da funcionalidade do tipo grep usandothe regex functionality no JDK também.