SED command not generating output file when called

2019-07-23 19:57发布

问题:

I am trying to write a java program that takes Strings in Java and replaces corresponding sequences of text in a perl script. Here is my code:

    String sedFirstLine = "'s/AAA/"+newFirstLine+"/'";
    String sedNewCntr = "'s/BBB/"+newCntr+"/'";
    String sedNewSpacing = "'s/SPACE/"+newSpacing+"/'";
    String sedNewDmax = "'s/MAX/"+newDmax+"/'";
    String sedInputFile = "/filepath/myPerlScript.pl" 
    String sedOutputFile = "/filepath/myNewPerlScript.pl";
    String[] cmdArray3 = {"sed", "-e", sedFirstLine,"-e", sedNewCntr,"-e", sedNewSpacing,"-e", sedNewDmax, "-e", sedInputFile, ">", sedOutputFile};
    Process runCmd;
    runCmd = Runtime.getRuntime().exec(cmdArray3);

When I run this program, the output file "myNewPerlScript.pl" is not generated. I'm not sure what is wrong with what I've written. The Java variables that I was referring to earlier are "newFirstLine", "newCntr", etc.

回答1:

This is because the output redirection (i.e. the > ) is a functionality of the shell. In order to redirect the output of the command, you can invoke the command through a shell. For example, with this command

String[] cmdArray3 = {"bash", "-c", "sed 's/AAA/BBB/' inputfile > output"};
Process runCmd = Runtime.getRuntime().exec(cmdArray3);

the output file should be created as expected.



回答2:

The ProcessBuilder version:

String sedFirstLine = "'s/AAA/"+newFirstLine+"/'";
String sedNewCntr = "'s/BBB/"+newCntr+"/'";
String sedNewSpacing = "'s/SPACE/"+newSpacing+"/'";
String sedNewDmax = "'s/MAX/"+newDmax+"/'";

File directory = new File("/filepath");
File sedInputFile = new File(directory, "myPerlScript.pl"); 
File sedOutputFile = new File(directory, "myNewPerlScript.pl");
List<String> commandLine = new ArrayList<>();
Collections.addAll(commandLine,
    "sed",
    "-e", sedFirstLine,
    "-e", sedNewCntr,
    "-e", sedNewSpacing,
    "-e", sedNewDmax);
ProcessBuilder pb = new ProcessBuilder(commandLine);
pb.directory(directory);
pb.redirectInput(Redirect.from(sedInputFile));
pb.redirectOutput(Redirect.to(sedOutputFile));
Process sed = pb.start();
// Watch sed.getErrorStream() for errors.

See the ProcessBuilder Javadoc.

You need not worry about shells, beacuse Java takes care of the redirection, as @Chris Stratton pointed out. Just make sure you handle the error stream somehow; if there are problems and too much error output piles up, the process may block. But the original method has the same problem.



回答3:

Just change the following line:

String[] cmdArray3 = {"sed", "-e", sedFirstLine,"-e", sedNewCntr,"-e", sedNewSpacing,"-e", sedNewDmax, "-e", sedFile};

to:

String[] cmdArray3 = {"sed", "-e", sedFirstLine,"-e", sedNewCntr,"-e", sedNewSpacing,"-e", sedNewDmax, sedFile};

Notice the extra -e parameter that you have.