JavaでGrepを使用したパターン検索
1. 概要
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. 結論
このクイックチュートリアルでは、Grep4jとUnix4Jを使用して特定のファイル内のパターンを検索する方法を説明しました。
これらの例の実装はthe GitHub projectにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。
最後に、JDKでもthe regex functionalityを使用して、grepのような機能の基本のいくつかを自然に行うことができます。