在Java文件中运行Unix命令

时间:2013-10-20 09:16:49

标签: java unix sed command-prompt

我试图在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

3 个答案:

答案 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);

我们不必担心使用此表单正确封装参数。