我试图在Java中执行以下命令(适用于终端):
awk -F';' 'NR>1{gsub(/; +/,";",$0);printf("{msisdn:\"%s\",imei:\"%s\",brand:\"%s\",model:\"%s\",sap:\"%s\",sap_cod:\"%s\",file_name:\"teste\",company:{\"$ref\":\"company\",\"$id\":ObjectId\"456\")}}\n",$2,$15,$16,$17,$18,$20)}' /Users/milena/Desktop/giant.csv
我正在使用的Java代码是:
String fileName = "test";
String company = "456";
String awk = "awk -F';' 'NR>1";
String gsub = "{gsub(/; +/,\";\",$0);";
String printf = "printf(\"{msisdn:\\\"%s\\\",imei:\\\"%s\\\",brand:\\\"%s\\\","
+ "model:\\\"%s\\\",sap:\\\"%s\\\",sap_cod:\\\"%s\\\",file_name:\\\""+fileName+"\\\",company:"
+ "{\\\"$ref\\\":\\\"company\\\",\\\"$id\\\":ObjectId\\\""+company+"\\\")}}\\n\",$2,$15,$16,$17,$18,$20)}\' ";
String path = "/Users/milena/Desktop/giant.csv";
String command = awk + gsub + printf + path;
Process p
p = Runtime.getRuntime().exec(command);
我得到的错误是:
awk: syntax error at source line 1
context is
>>> ' <<<
missing }
missing )
awk: bailing out at source line 1
关于我做错什么的任何想法?
答案 0 :(得分:3)
当你使用Runtime.getRuntime().exec(command)
时,它接受字符串并将其分解为基于空格的命令和参数。
这种简单的解析与调用命令时shell执行的解析不同。例如,shell考虑了引号。这意味着如果您有一个命令行,如:
cmd 'abc' 'def'
shell将发送到cmd
命令的参数将是abc
和def
。但是,如果您向Runtime.getRuntime().exec(command)
提供相同的命令,它会将'abc'
和'def'
作为参数发送给cmd
。是的,包括引号!
如果任何参数中有空格,情况会变得更糟。如果shell得到
cmd 'my single argument'
它将使用单个参数my single argument
调用该命令。但Runtime.getRuntime().exec(command)
会使用三个参数调用cmd
:'my
,single
和argument'
!
因此,除了非常简单的命令之外,不建议将此特定重载用于任何操作。相反,您应该使用接受字符串数组的重载。第一个元素应该是命令名,每个参数应该在一个单独的元素中:
String[] command = { "awk",
"-F;",
"NR>1{gsub(/; +/,\";\",$0);printf(\"{msisdn:\\\"%s\\\",...",
"/Users/milena/Desktop/giant.csv"
};
Process p = Runtime.getRuntime().exec(command);
注意:建议使用ProcessBuilder
类来构建Process
而不是Runtime.getRuntime.exec
- 它可以让您更好地控制命令,并且可以将单独的参数传递给构造函数。