首页 > 解决方案 > 如果命令有双引号,如何使用带有 bash -c 的 ProcessBuilder

问题描述

我必须加入两个基于多个列的大文件。Pipe(|) 符号是两个文件中的分隔符。

现在,我正在生成 unix join 命令,将其写入 shell 脚本,然后使用 ProcessBuilder 执行 shell 脚本以获得所需的输出。

该命令看起来像这样,

join -a 1 -a 2 -t \| -1 1 -2 1 -o 1.3,1.4,1.5,1.6,1.7,2.3,2.4,2.5,2.6,2.7 <(<"/home/input file 1" awk -F'|' 'NR>1{print $3"~&~"$4"|"$0}' | sort -k1 -t\| ) <(<"/home/input file 2" awk -F'|' 'NR>1{print $3~&~$4"|"$0}' | sort -k1 -t\| ) > "/home/output file"

这按预期工作。

我试图省略使用bash -c将命令写入 shell 脚本的步骤。但是我遇到问题主要是因为 awk 命令中的双引号(“)和美元($)。我试图使用反斜杠来转义它们,但没有用。

我目前使用的java代码是

long pid = -1;
try {
    StringBuilder completeCommand = new StringBuilder();
    for(String s: commands){
        completeCommand.append(s);
        completeCommand.append(" ");
    }
    completeCommand.append(" > \"");
    completeCommand.append(outputDir + File.separator + outputFileName);
    completeCommand.append("\"");
    File fileOutputDir = new File(outputDir);
    fileOutputDir.mkdirs();

    Files.writeString(Path.of(outputDir + File.separator + scriptName),
            completeCommand.toString(),
            new OpenOption[]{StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE,
                    StandardOpenOption.CREATE});

    ProcessBuilder processBuilder = new ProcessBuilder("bash", "\"" + outputDir + File.separator + scriptName + "\"");
    Process p = processBuilder.start();
    pid = p.pid();
    p.waitFor();
    return pid;
} catch (IOException | InterruptedException e) {
    log.error("Error in running join command" , e);
    return pid;
}

当我尝试使用 bash -c 时,我只是更改了 ProcessBuilder 语句,如下所示,

ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", completeCommand.toString());

这不会引发任何错误,但会生成一个空文件。

有什么办法可以解决这个问题吗?

任何帮助或建议都会很棒。

谢谢

标签: javabashjoinawkprocessbuilder

解决方案


推荐阅读