【问题标题】:Calling Grep inside Java gives incorrect results while calling grep in shell gives correct results在 Java 中调用 Grep 会得到不正确的结果,而在 shell 中调用 grep 会得到正确的结果
【发布时间】:2010-04-16 10:19:07
【问题描述】:

我遇到了一个问题,即从 java 内部调用 grep 得到的结果不正确,与在 shell 中对同一文件调用 grep 的结果相比。

我的 grep 命令(在 Java 和 bash 中都调用。我在 Java 中相应地转义了斜杠):

/bin/grep -vP --regexp='^[0-9]+\t.*' /usr/local/apache-tomcat-6.0.18/work/Catalina/localhost/saccitic/237482319867147879_1271411421

Java 代码:

String filepath = "/path/to/file";
String options = "P";
String grepparams = "^[0-9]+\\t.*";
String greppath = "/bin/";

String[] localeArray = new String[] {
    "LANG=",
    "LC_COLLATE=C",
    "LC_CTYPE=UTF-8",
    "LC_MESSAGES=C",
    "LC_MONETARY=C",
    "LC_NUMERIC=C",
    "LC_TIME=C",
    "LC_ALL="
};

options = "v"+options; //Assign optional params

if (options.contains("P")) {
    grepparams = "\'"+grepparams+"\'"; //Quote the regex expression if -P flag is used
} else {
    options = "E"+options; //equivalent to calling egrep
}

proc = sysRuntime.exec(greppath+"/grep -"+options+" --regexp="+grepparams+" "+filepath, localeArray);
System.out.println(greppath+"/grep -"+options+" --regexp="+grepparams+" "+filepath);
inStream = proc.getInputStream();

该命令应该匹配并丢弃如下字符串:

85295371616 Hi Mr Lee, please be informed that...

我的输入文件是这样的:

85aaa234567 Hi Ms Chan, please be informed that...
85292vx5678 Hi Mrs Ng, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85aaa234567 Hi Ms Chan, please be informed that...
85292vx5678 Hi Mrs Ng, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
8~!95371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
852&^*&1616 Hi Mr Lee, please be informed that...
8529537Ax16 Hi Mr Lee, please be informed that...
85====ppq16 Hi Mr Lee, please be informed that...
85291234783 a3283784428349247233834728482984723333
85219299222

当我从 bash 内部调用它时,这些命令有效(结果如下):

85aaa234567 Hi Ms Chan, please be informed that...
85292vx5678 Hi Mrs Ng, please be informed that...
85aaa234567 Hi Ms Chan, please be informed that...
85292vx5678 Hi Mrs Ng, please be informed that...
8~!95371616 Hi Mr Lee, please be informed that...
852&^*&1616 Hi Mr Lee, please be informed that...
8529537Ax16 Hi Mr Lee, please be informed that...
85====ppq16 Hi Mr Lee, please be informed that...
85219299222

但是,当我在 java 中再次调用 grep 时,我得到了整个文件(结果如下):

85aaa234567 Hi Ms Chan, please be informed that...
85292vx5678 Hi Mrs Ng, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85aaa234567 Hi Ms Chan, please be informed that...
85292vx5678 Hi Mrs Ng, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
8~!95371616 Hi Mr Lee, please be informed that...
85295371616 Hi Mr Lee, please be informed that...
852&^*&1616 Hi Mr Lee, please be informed that...
8529537Ax16 Hi Mr Lee, please be informed that...
85====ppq16 Hi Mr Lee, please be informed that...
85291234783 a3283784428349247233834728482984723333
85219299222

可能是什么问题会导致 Java 调用的 grep 返回不正确的结果?我尝试通过 runtime.exec 中的环境字符串数组传递本地信息,但似乎没有任何改变。我是否错误地传递了语言环境信息,或者问题完全是其他问题?

【问题讨论】:

  • 为什么要在 Java 中调用 grep?为什么不直接使用 Pattern 类并避免对 shell 进行外部调用?
  • 我将在生产环境中处理很多500k+行的文件,所以我需要依赖外部工具来完成。

标签: java bash grep exec locale


【解决方案1】:

shell 使用单引号,grep 看不到。你不应该在 java 中添加它们。

此外,您应该使用 exec(String[], String[]) 方法而不是连接参数,这样您就可以控制参数的分离。

我同意其他 cmets 的说法,您应该在纯 java 中执行此操作,而不是在单独的进程中启动 grep。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    相关资源
    最近更新 更多