Contents

使用Grep4j和Unix4J搜索模式

1. 概述

在本教程中——我们将学习如何在给定的文件中搜索模式——使用 Java 和第三方库,如Unix4JGrep4J

2. 背景

Unix 有一个名为grep的强大命令——它代表“全局正则表达式打印”。它在给定的文件集中搜索模式或正则表达式。

可以使用零个或多个选项以及 grep 命令来丰富搜索结果,我们将在下一节中详细介绍。 如果您使用的是 Windows,则可以按照此处 帖子中的说明安装 bash 。

3. 使用 Unix4j 库

首先,让我们看看如何使用 Unix4J 库来 grep 文件中的模式。

在下面的例子中——我们将看看如何在 Java 中翻译 Unix grep 命令。

3.1. 构建配置

在您的pom.xmlbuild.gradle添加以下依赖项:

<dependency>
    <groupId>org.unix4j</groupId>
    <artifactId>unix4j-command</artifactId>
    <version>0.4</version>
</dependency>

3.2. 使用 Grep 的示例

Unix 中的示例 grep:

grep "NINETEEN" dictionary.txt

Java中的等价物是:

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

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

另一个例子是我们可以在文件中使用反向文本搜索。这是相同的 Unix 版本:

grep -v "NINETEEN" dictionary.txt

这是上述命令的 Java 版本:

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

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

让我们看看,我们如何使用正则表达式在文件中搜索模式。这是计算整个文件中找到的所有正则表达式模式的 Unix 版本:

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

这是上述命令的 Java 版本:

@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. 使用 Grep4J

接下来——让我们看看如何使用 Grep4J 库在本地或远程位置的某个文件中对模式进行 grep。

在下面的例子中——我们将看看如何在 Java 中翻译 Unix grep 命令。

4.1. 构建配置

在您的pom.xmlbuild.gradle添加以下依赖项:

<dependency>
    <groupId>com.googlecode.grep4j</groupId>
    <artifactId>grep4j</artifactId>
    <version>1.8.7</version>
</dependency>

4.2. grep 示例

Java 中的示例 grep 即相当于:

grep "NINETEEN" dictionary.txt

这是命令的Java版本:

@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());
}

另一个例子是我们可以在文件中使用反向文本搜索。这是相同的 Unix 版本:

grep -v "NINETEEN" dictionary.txt

这是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()); 
}

让我们看看,我们如何使用正则表达式在文件中搜索模式。这是计算整个文件中找到的所有正则表达式模式的 Unix 版本:

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

这是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()); 
}