JavaでのGrepによるパターン検索

JavaでGrepを使用したパターン検索

1. 概要

このチュートリアルでは、JavaとUnix4JGrep4Jなどのサードパーティライブラリを使用して、search for a pattern in a given file/sを実行する方法を学習します。

2. バックグラウンド

Unixには、「global regular expression print」を表すgrepという強力なコマンドがあります。 指定された一連のファイル内でパターンまたは正規表現を検索します。

grepコマンドとともに0個以上のオプションを使用して、検索結果を充実させることができます。これについては、次のセクションで詳しく調べます。

Windowsを使用している場合は、投稿hereに記載されているようにbashをインストールできます。

3. unix4jライブラリを使用

最初に、Unix4Jライブラリを使用してファイル内のパターンをgrepする方法を見てみましょう。

次の例では、UnixのgrepコマンドをJavaで翻訳する方法を見ていきます。

3.1. ビルド構成

pom.xmlまたはbuild.gradleに次の依存関係を追加します。


    org.unix4j
    unix4j-command
    0.4

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 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 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する方法を見てみましょう。

次の例では、UnixのgrepコマンドをJavaで翻訳する方法を見ていきます。

4.1. ビルド構成

pom.xmlまたはbuild.gradleに次の依存関係を追加します。


    com.googlecode.grep4j
    grep4j
    1.8.7

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

5. 結論

このクイックチュートリアルでは、Grep4jUnix4Jを使用して特定のファイル内のパターンを検索する方法を説明しました。

これらの例の実装はthe GitHub projectにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。

最後に、JDKでもthe regex functionalityを使用して、grepのような機能の基本のいくつかを自然に行うことができます。