Reputation: 2664
I am trying to run a sed
command from java without success. Here is my java code:
String[] cmd = {"sed", "-i", "'"+lineIndex+"s/"+line+"/"+currentBid+"/g'", "/data/jsp/items.xml"};
Runtime.getRuntime().exec(cmd);
I also tried:
String[] cmd = {"/bin/sh","-c","sed", "-i", "'"+lineIndex+"s/"+line+"/"+currentBid+"/g'", "/data/jsp/items.xml"};
Runtime.getRuntime().exec(cmd);
Thing is, if I print out the contents of the cmd String
and run it in a terminal it does work. It's just not executing it from java for some reason. Te make this more clear, when I run the command directly from a terminal the file "items.xml" changes. When I run it from java the file does not change. I've verified that the command is correct as sown below.
Am I missing something?
The output from cmd is sed -i '21s/2/102/g' /data/jsp/items.xml
** EDIT
I made the following changes based on comments below. No change in output however.
String[] cmd = {"/bin/sh","-c","sed", "-i", "'"+lineIndex+"s/"+line+"/"+currentBid+"/g'", "/data/jsp/items.xml"};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line2 = reader.readLine();
while (line2 != null) {
line2 = reader.readLine();
}
reader.close();
Upvotes: 3
Views: 3569
Reputation: 15855
Honestly there is no need to externally execute sed
in this case. Read the file in Java and use Pattern
. Then you have code that could run on any platform. Combine this with org.apache.commons.io.FileUtils
and you can do it in a few lines of code.
final File = new File("/data/jsp/items.xml");
String contents = FileUtils.readFileToString(file, StandardCharsets.UTF_8.name());
contents = Pattern.compile(line).matcher(contents).replaceAll(currentBid);
FileUtils.write(file, contents);
Or, in a short, self-contained, correct example
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.regex.Pattern;
public final class SedUtil {
public static void main(String... args) throws Exception {
final File file = new File("items.xml");
final String line = "<bid>\\d+</bid>";
final String currentBid = "<bid>20</bid>";
final String data = "<bids><bid>10</bid></bids>";
FileUtils.write(file, data);
sed(file, Pattern.compile(line), currentBid);
System.out.println(data);
System.out.println(FileUtils.readFileToString(file, StandardCharsets.UTF_8));
}
public static void sed(File file, Pattern regex, String value) throws IOException {
String contents = FileUtils.readFileToString(file, StandardCharsets.UTF_8.name());
contents = regex.matcher(contents).replaceAll(value);
FileUtils.write(file, contents);
}
}
which gives output
<bids><bid>10</bid></bids>
<bids><bid>20</bid></bids>
Upvotes: 0
Reputation: 514
You need to make sure the path to the file is correct, java may not have the same path to the file unless it is in the jar. You can do this by trying to open the file or checking if it exists before passing it to the command.
see: How to read file from relative path in Java project? java.io.File cannot find the path specified
Upvotes: 1
Reputation: 1336
Try that :)
The advantage of this solution , it's more easier to debugging because you have the temporary file !
String lineIndex="21";
String line="2";
String currentBid="102";
File temp = File.createTempFile("temp-sh", ".sh");
FileWriter fw = new FileWriter(temp);
fw.write("#!/bin/bash\n");
fw.write("sed -i '"+lineIndex+"s/"+line+"/"+currentBid+"/g' data/jsp/items.xml\n");
fw.close();
System.out.println(". "+temp.getAbsolutePath());
Runtime.getRuntime().exec(". "+temp.getAbsolutePath());
Upvotes: 1
Reputation: 201477
You should probably use a ProcessBuilder instead of Runtime.exec
, perhaps something like this -
try {
String replaceCommand ="'"+lineIndex+"s/"+line+"/"+currentBid+"/g'";
String [] cmd = new String[] {
"sed", "-i", replaceCommand, "/data/jsp/items.xml"
};
Process process = new ProcessBuilder(cmd)
.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String lineRead;
System.out.printf("Output of running %s is:",
Arrays.toString(cmd));
while ((lineRead = br.readLine()) != null) {
System.out.println(lineRead);
}
} catch (IOException e) {
e.printStackTrace();
}
Upvotes: 1