如何使用Java为awk输入正确转义字符串?
我试图在Java中执行以下命令(在终端上工作):如何使用Java为awk输入正确转义字符串?,java,string,unix,awk,Java,String,Unix,Awk,我试图在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,$
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
awk:源代码第1行出现语法错误
上下文是
>>>“当您使用Runtime.getRuntime().exec(command)
时,它会获取字符串并根据空格将其分解为命令和参数
这个简单的解析与调用命令时shell完成的解析不同。例如,shell考虑了引号。这意味着如果您有如下命令行:
cmd 'abc' 'def'
shell将发送给cmd
命令的参数将是abc
和def
。但是如果您向Runtime.getRuntime().exec(command)
发出相同的命令,它将'abc'
和'def'
作为参数发送到cmd
。是的,包括引号强>
如果在任何参数中都有空格,情况会变得更糟。如果外壳
cmd 'my single argument'
它将使用单个参数调用命令my single argument
。但是Runtime.getRuntime().exec(command)
将使用三个参数调用cmd
,单个
和参数
因此,除了非常简单的命令外,不建议对任何东西使用此特定重载。相反,您应该使用接受字符串数组的重载。第一个元素应为命令名,每个参数应位于单独的元素中:
String[] command = { "awk",
"-F;",
"NR>1{gsub(/; +/,\";\",$0);printf(\"{msisdn:\\\"%s\\\",...",
"/Users/milena/Desktop/giant.csv"
};
Process p = Runtime.getRuntime().exec(command);
注意:建议使用该类来构建一个进程
,而不是Runtime.getRuntime.exec
——它使您能够更好地控制命令,并且可以将单独的参数直接传递给构造函数。我认为,要么在缺少单引号的地方结束,要么在缺少单引号的地方对进程进行编码。。。不是通过尝试…抓住。。。所以,请您这样做,然后让我知道,如果仍然有任何问题或没有。谢谢您的回答,我会看看ProcessBuilder很快。然而,当我尝试用字符串数组调用命令时,它显然进入了一个无限循环。知道为什么吗?它没有给我任何错误。@MilenaAraujo它是一个awk程序-它有任何输出吗?您正在读取输出吗?如果不这样做,那么进程可能会被阻塞,等待Java读取其输出。如果希望将输出转到控制台,则必须使用ProcessBuilder
。如果您想在Java中处理它,您应该读取进程的输出流
代码>它确实有一个输出(它正在从csv转换为json)。所以,如果有输出,您如何检测它在无限循环中?完成文件中的最后一行后会发生什么?您是否也在检查标准错误流?也许您应该为此提出一个新问题,并提供所有相关的代码(最好是一个)以及一个示例输入文件。我按照您的建议使用了ProcessBuilder,现在一切正常,正如预期的那样!再次感谢:)