2013-11-27 108 views
2

我试图从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(); 
+0

好像它会更好,对我来说,到流的XML中Java并执行搜索并以Java替换,而不是从外部shell执行'sed' – Kirby

回答

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

我收到一条错误消息:线程“main”中的异常java.io.IOException:无法运行程序“。”:java.io.IOException:error = 13,权限被拒绝 – cHam

+0

而不是File.createTempFile,在你有权限的目录 –

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

你需要确保的文件路径是正确的,JAVA可能不会有相同的路径该文件,除非它在罐子里。您可以通过在将文件传递给命令之前打开文件或检查它是否存在来做到这一点。

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

+0

我不确定你的意思。文件items.xml永远不会改变,读取输入流如何改变文件? – cHam

+0

对不起,我没有意识到这个例子中缺少p的类型。 p是您访问输出的类型进程,请参阅:http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html –

+0

对不起,我没有意识到该示例缺少类型页。 p是通过其getInputStream方法访问输出的类型流程。见:HTTP://docs.oracle.com/javase/7/docs/api/java/lang/Process。html –

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>