[英]How can I correctly escape string for awk input using Java?
I'm trying to execute the following command (which works on the terminal) within Java: 我正在尝试在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
The Java code I am using is this: 我正在使用的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);
The error I am getting is: 我得到的错误是:
awk: syntax error at source line 1
context is
>>> ' <<<
missing }
missing )
awk: bailing out at source line 1
Any ideas of what am I doing wrong? 我有什么不对的想法吗?
When you use Runtime.getRuntime().exec(command)
, it takes the string and breaks it into a command and arguments based on spaces. 当您使用
Runtime.getRuntime().exec(command)
,它接受字符串并将其分解为基于空格的命令和参数。
This simple parsing is not the same as the parsing done by the shell when you invoke the command. 这种简单的解析与调用命令时shell执行的解析不同。 The shell, for example, takes quotes into consideration.
例如,shell考虑了引号。 This means that if you have a command line like:
这意味着如果你有一个命令行,如:
cmd 'abc' 'def'
The arguments that the shell will send to the cmd
command are going to be abc
and def
. shell将发送到
cmd
命令的参数将是abc
和def
。 But if you give the same command to Runtime.getRuntime().exec(command)
, it will send 'abc'
and 'def'
to cmd
as arguments. 但是如果你给
Runtime.getRuntime().exec(command)
提供相同的命令,它会将'abc'
和'def'
作为参数发送给cmd
。 Yes, including the quotes! 是的, 包括报价!
The situation gets worse if you have spaces in any of the arguments. 如果在任何参数中都有空格,情况会变得更糟。 If the shell gets
如果shell得到了
cmd 'my single argument'
It will invoke the command with a single argument my single argument
. 它会调用带一个参数的命令,
my single argument
。 But Runtime.getRuntime().exec(command)
will invoke cmd
with three arguments: 'my
, single
and argument'
! 但
Runtime.getRuntime().exec(command)
将使用三个参数调用cmd
: 'my
, single
和argument'
!
So it's not recommended to use this particular overload for anything but very simple commands. 因此,除了非常简单的命令之外,不建议将此特定重载用于任何操作。 Instead, you should use the overload that accepts an array of strings.
相反,您应该使用接受字符串数组的重载。 The first element should be the command name, and each argument should be in a separate element:
第一个元素应该是命令名,每个参数应该在一个单独的元素中:
String[] command = { "awk",
"-F;",
"NR>1{gsub(/; +/,\";\",$0);printf(\"{msisdn:\\\"%s\\\",...",
"/Users/milena/Desktop/giant.csv"
};
Process p = Runtime.getRuntime().exec(command);
Note: It is recommended to use the ProcessBuilder
class to build a Process
rather than Runtime.getRuntime.exec
- it gives you better control of the command and you can pass the separate arguments right to the constructor. 注意:建议使用
ProcessBuilder
类来构建Process
而不是Runtime.getRuntime.exec
- 它可以让您更好地控制命令,并且可以将单独的参数传递给构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.