2013-10-20 54 views
0

我試圖在Java運行UNIX命令忽略雙引號在解析文件上運行UNIX命令:在Java文件

for(int i = 0; i < numTables; i++){ 
     try{ 
      String command = "sed -e \'s/\"/\"\"/g\' -e \'s/^/\"/\' -e \'s/$/\"/\' -e \'s/<>/\"<>\"/g\' input.dat > output.dat"; 
      Process p = Runtime.getRuntime().exec(command); 
     } catch(IOException ioe){ 
      System.out.println("Error executing command"); 
     } 
    } 

然而,在終端上鍵入相同的命令直接會工作。 任何想法出了什麼問題? 謝謝!

更新: 其實,我嘗試以下(使用數組,而不是隻是一個字符串)的,它太失敗:

  String[] command = new String[] {"sed", "-e", "\'s/\"/\"\"/g\'", "-e", "\'s/^/\"/\'", "-e", "\'s/$/\"/\'", "-e", "\'s/<>/\"<>\"/g\'", prefixedFileList.get(i), ">", fileList.get(i)}; 
      Process p = Runtime.getRuntime().exec(command); 

有什麼想法?

作爲一個更清晰的畫面,這將UNIX終端上執行將

sed -e 's/"/""/g' -e 's/^/"/' -e 's/$/"/' -e 's/<>/"<>"/g' input.dat > output.dat 
+1

它是如何失敗?你有沒有遇到錯誤,或者什麼都沒有發生? – Renan

+1

獲取進程的輸出流並進行打印。可能錯誤應該暴露在那裏。 –

+0

尋找類似的東西? http://stackoverflow.com/questions/7134486/how-to-execute-command-with-parameters – AppX

回答

0

井你是不是把\一些特殊字符對應的明文?你可以把相同的。

0

它有助於準確區分程序參數是什麼。當您執行這行:

sed -e 's/"/""/g' -e 's/^/"/' -e 's/$/"/' -e 's/<>/"<>"/g' input.dat > output.dat 

main方法的sed二進制文件與其argv接收這些字符串:

  • sed
  • -e
  • s/"/""/g
  • -e
  • s/^/"/
  • -e
  • s/$/"/
  • -e
  • s/<>/"<>"/g
  • input.dat

注意,單引號(')不是的程序參數的一部分。單引號由shell解釋(bash,csh等)。他們告訴shell不要評估或解析它們內部的內容。 shell採用一個單引號字符串並按原樣將它傳遞給程序,但單引號不是參數的一部分。它們僅用於殼體。

另請注意,文件重定向> output.dat不是程序參數的一部分。文件重定向由shell解析。知道其標準輸出是否被重定向並不是一個程序的工作;該程序無論寫入標準輸出,操作系統都執行重定向。如果您嘗試通過> output.dat作爲程序參數,sed將查找名爲>的附加輸入文件和名爲output.dat的附加輸入文件。

最好調用一個Runtime.exec方法,該方法使用一個數組而不是一個String,就像你已經知道的那樣。甚至比這更好的是使用ProcessBuilder類,它可以做到輸出重定向,實質上重複的>在外殼的功能:

ProcessBuilder builder = new ProcessBuilder(
    "sed", 
    "-e", 
    "s/\"/\"\"/g", 
    "-e", 
    "s/^/\"/", 
    "-e", 
    "s/$/\"/", 
    "-e", 
    "s/<>/\"<>\"/g", 
    "input.dat"); 
builder.redirectOutput(new File("output.dat")); 
builder.redirectError(ProcessBuilder.Redirect.INHERIT); 

Process p = builder.start(); 
+0

這似乎是一個非常合理的答案。但是,當我嘗試時,它仍然失敗........... :( –

+0

它是如何失敗的?你看到一個異常嗎? – VGR

+0

嘗試添加'builder.redirectError(ProcessBuilder.Redirect.INHERIT);'所以** sed **顯示的任何錯誤都可以在程序輸出中看到,我已經更新了我的答案。 – VGR

0

之一,它使用Apache Commons Exec庫的最佳解決方案。

下面是我最喜歡的用法:

CommandLine cmdLine = new CommandLine("AcroRd32.exe"); 
cmdLine.addArgument("/p"); 
cmdLine.addArgument("/h"); 
DefaultExecutor executor = new DefaultExecutor(); 
executor.setExitValue(1); 
int exitValue = executor.execute(cmdLine); 

我們不必擔心使用適當這種形式封裝的論點。