4

在过去的 3 天里,我在谷歌上没有太多运气来了解如何从 Java 中运行 grep 进程。

我有以下代码来运行 grep 进程,但是,我只得到响应的第一行。

package com.example.parser;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) {
        try {
            Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/").start();

            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line = "";
            while((line = br.readLine()) != null) {
                System.out.println(line);
            }

            System.out.println("Exit Code: " + process.exitValue());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

我只收到以下回复:

Binary file /home/user/dev/java/Parser/parser/bin/com/example/parser/Main.class matches
Exit Code: 0

当我应该得到以下响应时:

Binary file /home/user/dev/java/Parser/parser/com/example/parser/Main.class matches
/home/user/dev/java/Parser/parser/src/com/example/parser/Main.java:10:  public static void main(String[] args) {
/home/user/dev/java/Parser/parser/src/com/example/parser/Main.java:12:          Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
Exit Code: 0

我想知道为什么我只得到第一个发现的输出?grep 是否分叉了几个进程来运行搜索,而我只处理第一个进程?


我也尝试过从线程运行进程:

包 com.example.parser;

public class Main {

    public static void main(String[] args) {
        try {
            Analyzer analyzer = new Analyzer();
            analyzer.start();
            analyzer.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}


package com.example.parser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Analyzer extends Thread {

    public Analyzer() {
    }

    @Override
    public void run() {
        try {
            Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
            process.waitFor();
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line = "";
            while((line = br.readLine()) != null) {
                System.out.println(line);
            }

            System.out.println("Exit Code: " + process.exitValue());

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

以及以下内容:

package com.example.parser;

import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try {
            Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
            process.waitFor();

            Analyzer analyzer_is = new Analyzer(process.getInputStream());
            Analyzer analyzer_es = new Analyzer(process.getErrorStream());

            analyzer_is.start();
            analyzer_es.start();

            analyzer_is.join();
            analyzer_es.join();

            System.out.println("Exit Code: " + process.exitValue());

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

package com.example.parser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Analyzer extends Thread {

    InputStream is = null;

    public Analyzer(InputStream is) {
        this.is = is;
    }

    @Override
    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(this.is));

            String line = "";
            while((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

正如以下文章所建议的那样:http ://www.javaworld.com/jw-12-2000/jw-1229-traps.html

4

4 回答 4

2

我能够通过启动带有 -c 标志的 shell 来解决这个问题。以下代码符合我最初的意图:

package com.example.parser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        try {
            List<String> commands = new ArrayList<String>();
            commands.add("/bin/sh");
            commands.add("-c");
            commands.add("grep -rni --include \"*.java\" \"public static void main(\" /home/user/dev/java/Parser/parser");

            Process process = new ProcessBuilder(commands).start();
            Analyzer analyzer_is = new Analyzer(process.getInputStream());
            Analyzer analyzer_es = new Analyzer(process.getErrorStream());

            analyzer_is.start();
            analyzer_es.start();

            process.waitFor();

            analyzer_is.join();
            analyzer_es.join();

            System.out.println("Exit Code: " + process.exitValue());

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}


package com.example.parser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Analyzer extends Thread {

    InputStream is = null;

    public Analyzer(InputStream is) {
        this.is = is;
    }

    @Override
    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(this.is));

            String line = "";
            while((line = br.readLine()) != null) {
                  System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
于 2012-11-16T17:54:40.337 回答
1

这可能是因为您没有等待 grep 完成。

使用waitFor 方法

Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/").start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
process.waitFor();
String line = "";
while((line = br.readLine()) != null) {
      System.out.println(line);
}

请注意,您还可以在使用处理输出时读取输出(主要是为了了解发生了什么)

Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"",     String line;
while (true) {
    line = reader.readLine(); // add IO exception catching
    if (line != null) {
      System.out.println(line);
    } else {
        Thread.sleep(DELAY);   // DELAY could be 100 (ms) for example     
    }
}

我想你确定 java 程序的所有者启动的 grep 不止一行?

于 2012-11-15T15:47:37.900 回答
0

另一个原因可能是您的进程仍在运行,但您的 Java 程序刚刚退出。

使用 process.waitFor(); 并在线程中读取您的输入流。

开始这个过程。以进程输入流作为输入的午餐线程。现在使用 process.waitFor(); 等待进程退出

这可能会有所帮助!

于 2012-11-15T15:50:22.487 回答
0

看看这个项目在java中的grep https://code.google.com/p/grep4j

于 2013-04-10T09:00:36.213 回答