我试图在java中运行unix命令忽略解析文件中的双引号:
for(int i = 0; i < numTables; i++){
try{
String command = "sed -e \'s/\"/\"\"/g\' -e \'s/^/\"/\' -e \'s/$/\"/\' -e \'s/<>/\"<>\"/g\' input.dat > output.dat";
Process p = Runtime.getRuntime().exec(command);
} catch(IOException ioe){
System.out.println("Error executing command");
}
}
但是,直接在终端上输入相同的命令会起作用。 知道出了什么问题吗? 谢谢!
更新: 事实上,我尝试了以下(使用数组而不仅仅是一个字符串),它也失败了:
String[] command = new String[] {"sed", "-e", "\'s/\"/\"\"/g\'", "-e", "\'s/^/\"/\'", "-e", "\'s/$/\"/\'", "-e", "\'s/<>/\"<>\"/g\'", prefixedFileList.get(i), ">", fileList.get(i)};
Process p = Runtime.getRuntime().exec(command);
有什么想法吗?
作为更清晰的图片,将在unix终端上执行的相应纯文本将是
sed -e 's/"/""/g' -e 's/^/"/' -e 's/$/"/' -e 's/<>/"<>"/g' input.dat > output.dat
答案 0 :(得分:0)
在某些特殊角色中,你没有放置\?你能把它放一样吗。
答案 1 :(得分:0)
它有助于准确区分程序参数。执行此行时:
sed -e 's/"/""/g' -e 's/^/"/' -e 's/$/"/' -e 's/<>/"<>"/g' input.dat > output.dat
sed 二进制文件的main
方法在其argv中接收这些字符串:
sed
-e
s/"/""/g
-e
s/^/"/
-e
s/$/"/
-e
s/<>/"<>"/g
input.dat
请注意,单引号('
)不是程序参数的一部分。单引号由shell解释(bash,csh等)。他们告诉shell不要评估或解析它们内部的内容。 shell使用单引号字符串并按原样将其传递给程序,但单引号不是参数的一部分。它们只是为了shell的利益。
另请注意,文件重定向> output.dat
不是程序参数的一部分。文件重定向由shell解析。了解其标准输出是否被重定向不是程序的工作;程序无论如何写入标准输出,操作系统执行重定向。如果您尝试将> output.dat
作为程序参数传递, sed 将查找名为>
的其他输入文件和名为output.dat
的其他输入文件。
最好调用一个Runtime.exec方法,它接受一个数组而不是一个String,就像你似乎已经知道的那样。更好的是使用ProcessBuilder
类,它可以进行输出重定向,基本上复制了shell中>
的功能:
ProcessBuilder builder = new ProcessBuilder(
"sed",
"-e",
"s/\"/\"\"/g",
"-e",
"s/^/\"/",
"-e",
"s/$/\"/",
"-e",
"s/<>/\"<>\"/g",
"input.dat");
builder.redirectOutput(new File("output.dat"));
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
Process p = builder.start();
答案 2 :(得分:0)
使用Apache Commons Exec库的最佳解决方案之一。
以下是我最喜欢的用法:
CommandLine cmdLine = new CommandLine("AcroRd32.exe");
cmdLine.addArgument("/p");
cmdLine.addArgument("/h");
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
int exitValue = executor.execute(cmdLine);
我们不必担心使用此表单正确封装参数。