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.
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.
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.
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.