sed命令不能从java工作

时间:2013-11-27 02:13:51

标签: java sed

我试图从java运行sed命令但没有成功。这是我的java代码:

String[] cmd = {"sed", "-i", "'"+lineIndex+"s/"+line+"/"+currentBid+"/g'", "/data/jsp/items.xml"};
        Runtime.getRuntime().exec(cmd);

我也尝试过:

String[] cmd = {"/bin/sh","-c","sed", "-i", "'"+lineIndex+"s/"+line+"/"+currentBid+"/g'", "/data/jsp/items.xml"};
        Runtime.getRuntime().exec(cmd);

事情是,如果我打印出cmd String的内容并在终端中运行它确实有效。它只是因为某种原因没有从java执行它。更清楚的是,当我直接从终端运行命令时,文件“items.xml”发生了变化。当我从java运行它时,文件不会改变。我已经验证了命令是正确的,如下所示。

我错过了什么吗?

cmd的输出为sed -i '21s/2/102/g' /data/jsp/items.xml

**编辑

我根据以下评论做了以下更改。但是输出没有变化。

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();

4 个答案:

答案 0 :(得分:1)

你应该使用ProcessBuilder而不是Runtime.exec,也许是这样的 -

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();
}

答案 1 :(得分:1)

您需要确保文件的路径是正确的,java可能没有相同的文件路径,除非它在jar中。您可以通过在将文件传递给命令之前尝试打开文件或检查文件是否存在来执行此操作。

请参阅:How to read file from relative path in Java project? java.io.File cannot find the path specified

答案 2 :(得分:0)

试试:)

此解决方案的优点是,因为您拥有临时文件,所以更容易调试!

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());

答案 3 :(得分:0)

老实说,在这种情况下,无需外部执行sed。用Java读取文件并使用Pattern。然后,您拥有可以在任何平台上运行的代码。将其与org.apache.commons.io.FileUtils结合使用,您可以在几行代码中完成。

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

或者,在一个简短的,自足的,正确的例子中

    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);
    }
}

给出输出

<bids><bid>10</bid></bids>
<bids><bid>20</bid></bids>