【问题标题】:Running a grep command using java Runtime api使用 java Runtime api 运行 grep 命令
【发布时间】:2014-01-02 04:40:07
【问题描述】:

我需要在 unix 服务器的文件列表(文件数量很大)中 grep 一些文本,然后在 web gui 中列出文件名。所以我决定实现这一点的最佳方法是使用 Runtime.getRuntime() 编写一个 unix 命令执行器。 适用于大多数 unix 命令,但面临这个奇怪的 grep 问题。

首先是代码:

public class UnixCommandExecutor {

    private static StringBuffer output = new StringBuffer();

    public static String exec(String command) throws Exception{
        Process process = null;
        process = Runtime.getRuntime().exec(command);
        BufferedReader stdErr = getBufferedReader(process.getErrorStream());
        BufferedReader stdIn = getBufferedReader(process.getInputStream());
        StringBuffer data = extractData(stdErr);
        if (data.length() >= 1) {
            System.out.println("Error: " +data.toString());
            throw new Exception(data.toString());
        }
        data = extractData(stdIn);
        if (data.length() >= 1) {
            output = data;
            System.out.println("Output: " +data.toString());
        }
        return output.toString();
    }

    private static BufferedReader getBufferedReader(InputStream stream) {
        InputStreamReader inReader = new InputStreamReader(stream);
        BufferedReader buffReader = new BufferedReader(inReader);
        return buffReader;
    }

    private static StringBuffer extractData(BufferedReader reader)
            throws IOException {
        StringBuffer data = new StringBuffer();
        String s = "";
        while ((s = reader.readLine()) != null) {
            data.append(s + "\n");
        }
        return data;
    }

    public StringBuffer getOutput() {
        return output;
    }
}

现在调用将是这样的: 字符串输出 = exec("find .-name blah"); 这工作正常,结果是完美的。或者任何其他 unix 命令执行并正确提供结果。

但是当使用 grep 命令时,它会给出一个奇怪的错误: 字符串输出 = exec("grep -l 执行器 *");

Error: grep: *: No such file or directory

这很奇怪,因为如果我直接在 unix 上运行这个命令,它会给出想要的结果。 还尝试给文件路径提供类似的东西, 字符串输出 = exec("grep -l 执行器 /file/path/*"); 即使这样,错误是:

Error: grep: /file/path/*: No such file or directory

有什么想法吗?或任何其他更好的方法来解决这个问题? 欢迎提出任何建议。

【问题讨论】:

  • 好的..我得到了这个工作。基本上我需要两件事才能让它工作。首先使用/bin/sh -c,其次使用Runtime.exec(String[]) api。所以总的来说,我的方法调用现在看起来像 String[] commands = new String[]{"/bin/sh","-c","grep -l executor *"}; exec(commands); 工作得很好,结果显示了

标签: java unix grep runtime


【解决方案1】:

* 由 shell 解释,而不是 grep 本身。所以如果你从你的 Java 程序启动 grep 是行不通的。

您可以使用grep-r 使其递归搜索,然后将. 用于当前目录:

grep -lr executor .

要模拟 shell 的行为,只需将 * 替换为您要搜索的文件夹中所有文件的空格分隔列表。您可以使用以下命令获取所有文件的列表:

StringBuilder str = new StringBuilder();

for (File f : new File("your folder").listFiles()) {
    if (f.isFile()) {
        str.append(' ').append(f.getPath());
    }
}

现在只需将* 替换为str.toString() 的结果。

【讨论】:

  • 我猜你很清楚 * 是由 shell 解释的,这就是我面临这个问题的原因。但是使用 grep . 并递归地使用是昂贵的并且会影响性​​能,因为它将包含不需要的文件到 grep 中,我想避免这些文件。另一方面,在 grep 中处理 * 的最佳方法是什么?有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2021-09-09
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 2020-11-24
  • 2011-09-15
  • 1970-01-01
相关资源
最近更新 更多