如何使用Java为awk输入正确转义字符串?

如何使用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,$

我试图在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
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,现在一切正常,正如预期的那样!再次感谢:)