java - 如果命令有双引号,如何使用带有 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());
这不会引发任何错误,但会生成一个空文件。
有什么办法可以解决这个问题吗?
任何帮助或建议都会很棒。
谢谢
解决方案
推荐阅读
- javascript - 如何从对象数组中获取唯一值
- javascript - 连接集合中元素的所有数组 [MongoDB]
- ruby-on-rails-4 - 更好地使用每个并检查类型与在哪里过滤 ActiveRecord 关系中的类型
- angular - 当列表初始化为空时,使用 ngFor 创建 mat-option 元素
- .net - 无法读取“GetProcessPreferredUILanguages”函数返回的所有语言名称
- php - 如何隐藏表格中的空字段?
- java - 带有 Spring 的 DDD Java - 返回 Mono/Flux 的存储库
- reactjs - Redux - 当我调度一个动作时,Reducer 没有被调用
- r-markdown - 如何将 YAML 中的动态参数传递到 word 文档每一页中出现的标题?
- google-apps-script - 将工作表保持在 500 行