使用Java运行AWK Shell脚本时无响应
我正在尝试从Java使用awk.我写了下面的代码,但没有输出.
I am trying to use awk from java. I wrote below code but there is no output.
public class ShellScriptExecution {
public static void main (String[] a) {
ShellScriptExecution shellsc = new ShellScriptExecution();
String command = "awk '/Ayushi/ {print}' /home/ayushi/Desktop/testAwk.txt ";
String op = shellsc.execute(command, a);
System.out.println(op);
}
private String execute(String command, String[] a) {
StringBuffer sb = new StringBuffer();
Process p;
try {
//
//
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
sb.append(line + "\n");
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return sb.toString();
}
}
请提供有关如何在Java中使用awk的帮助?还有其他方法吗?
Please provide some help on how to use awk in java? And if any other way to do it ?
其他答案不是无效的,但是您的代码存在多个问题.是的,您无法正确管理错误/输出的读取.但是除此之外,您还误以为Runtime.getRuntime().exec类似于bash.不是.
The other answers aren't invalid, but there are multiple issues with your code. Yes, you're not managing your reads of error/output correctly. But in addition, you're making the mistake of thinking that Runtime.getRuntime().exec is bash-like. It isn't.
当您键入以下内容时:
awk '/Ayushi/ {print}' /home/ayushi/Desktop/testAwk.txt
在bash中,bash在实际调用awk之前对其进行了很多预处理.它执行以下操作:
in bash, bash preprocesses a lot of that before it actually invokes awk. It does these things:
- 它使用环境
PATH
变量来确定awk
是对/usr/bin/awk
的引用. - 它将解析包含该空格作为第一个参数的字符串
/Ayushi {print}
.在这种情况下,bash会使用单引号. - 它采用了testAwk的路径,却无所事事(它没有被引用并且不包含变量,星号或问号).
- 但是,尾随的空间...被消除了.
- It uses the environment
PATH
variable to figure out thatawk
is a reference to presumably/usr/bin/awk
. - It parses the string
/Ayushi {print}
including that space as the first parameter. As part of this, the single quotes are consumed by bash. - It takes the path to testAwk and sees nothing to do (it isn't quoted and contains no variables or stars or question marks).
- That trailing space, however... that is eliminated.
因此,它将使用参数["/Ayushi {print}","/home/ayushi/Desktop/testAwk.txt"]调用/usr/bin/awk
Therefore, it will invoke /usr/bin/awk with as parameters ["/Ayushi {print}", "/home/ayushi/Desktop/testAwk.txt"]
Java不是bash .根据运行Java的操作系统,它要么不执行任何操作,要么不执行任何操作.最好假设Java不会做任何事情. (此外,假设像*.txt
这样的东西将无法工作.在Windows中,它可能会或可能不会工作,在linux和mac上肯定不会工作.将*.txt
扩展到与该通配符匹配的文件列表是很重要的事情. bash可以).
Java is not bash. It is going to do either none of those things, or only a few of those things, depending on the OS you run java on. It is best to assume java will do none of those things. (Also, assume something like *.txt
just is not going to work. In windows it may or may not work, in linux and mac that definitely would not work. Expanding *.txt
to a list of files that match that wildcard is something bash does).
对于初学者,请勿使用Runtime.getRuntime().exec().始终使用ProcessBuilder
,或者至少使用exec方法,该方法采用参数列表而不是单个字符串.然后,将以下内容作为命令行参数传递:
For starters, never use Runtime.getRuntime().exec(). Always use ProcessBuilder
, or at the very least, the exec method which takes a list of parameters instead of a single string. Then, pass the following as command line argument:
ProcessBuilder pb = new ProcessBuilder(
"/usr/bin/awk",
"/Ayushi {print}",
"/home/ayushi/Desktop/testAwk.txt"
);
// configure other things, such as redirecting error to output and such...
Process p = pb.start();
// start handling the outputs.
然后从那里拿走.您可以仔细阅读ProcessBuilder
上的文档,以了解在实际调用之前要进行的有用设置以及可以使用Process p
变量进行的操作.
Then take it from there. You can peruse the docs on ProcessBuilder
for useful things to set prior to actually invoking, and things you can do with your Process p
variable.
NB:看来您正在Windows内的某些Linux仿真层中运行事物,这肯定会使事情变得更复杂.
NB: It looks like you're running things inside some linux emulation layer inside windows, that's definitely going to make things more complicated.