使用Java运行AWK Shell脚本时无响应

时间:2018-09-10 09:24:50

标签: java awk

我正在尝试从Java使用awk。我写了下面的代码,但没有输出。

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的帮助?还有其他方法吗?

3 个答案:

答案 0 :(得分:0)

这只是一个建议,因为由于信誉分数不足,我仍然无法发表评论。您为什么不只创建一个本地Shell脚本,然后在其中执行<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all" version="3.0"> <xsl:mode on-no-match="shallow-copy"/> <xsl:output method="xml" indent="yes"/> <xsl:key name="city-by-id" match="Cities/City" use="@id"/> <xsl:variable name="sort-order" as="element()*"> <wPart>Africa</wPart> <wPart>Europe</wPart> <wPart>Americas</wPart> </xsl:variable> <xsl:template match="VisitedCities"> <xsl:copy> <xsl:apply-templates select="VisitedCity"> <xsl:sort select="index-of($sort-order, key('city-by-id', @cityID)/@worldPart)"/> <xsl:sort select="Date"/> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet> 命令并使用Java触发所述Shell脚本?我认为这更方便。在这个问题中,您想在Java中使用xsl:mode,但实际上,它是可以在Shell脚本中使用的“命令行实用程序”。如果您真的想在Java中使用<!-- Copy everything that does not match later templates. -->,则可以尝试搜索第三方库。

答案 1 :(得分:0)

您需要获取过程的输出。因此,您可以修改命令,例如it prints result into a text file。该过程完成工作后,您可以读取文件。

  runcomand > output_file.txt

或者您可以创建一个流并读取输出example is here

BufferedReader stdInput = new BufferedReader(new 
InputStreamReader(proc.getInputStream()));

BufferedReader stdError = new BufferedReader(new 
InputStreamReader(proc.getErrorStream()));

我用CURL做过类似的事情。我需要从Java程序运行CURL进程并获取输出。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import static com.my.util.FileUtils.saveContent;

public class CurlProcess {

    private static final String CURL = "curl";
    private static final String RESPONSE_DIRECTORY = "C:/responses";

    static {
        FileUtils.createDirectory(RESPONSE_DIRECTORY);
    }

    public void execute(String url, String filename) {
        ProcessBuilder pb = new ProcessBuilder(
                CURL,
                "-s",
                "-i",
                url);

        pb.directory(new File(RESPONSE_DIRECTORY));
        pb.redirectErrorStream(true);
        Process p = null;

        String outputFile = RESPONSE_DIRECTORY + "/" + filename;
        try {
            p = pb.start();
            InputStream is = p.getInputStream();
            OutputStream os = new FileOutputStream(outputFile);
            saveContent(is, os);

            is.close();
        } catch (IOException e) {
            throw new RuntimeException("Failed to start curl process.", e);
        }
    }
}

答案 2 :(得分:0)

其他答案不是无效的,但是您的代码存在多个问题。是的,您无法正确管理错误/输出的读取。但是除此之外,您还误以为Runtime.getRuntime()。exec类似于bash。不是。

当您键入以下内容时:

awk '/Ayushi/ {print}' /home/ayushi/Desktop/testAwk.txt

在bash中,bash在实际调用awk之前对其进行了很多预处理。它执行以下操作:

  1. 它使用环境PATH变量来确定awk是对/usr/bin/awk的引用。
  2. 它将解析包含该空格作为第一个参数的字符串/Ayushi {print}。其中一部分是bash使用单引号。
  3. 它采用了testAwk的路径,却无所事事(它没有被引用并且不包含变量,星号或问号)。
  4. 但是,尾随空间...已被消除。

因此,它将使用参数[“ / Ayushi {print}”,“ / home / ayushi / Desktop / testAwk.txt”]调用/ usr / bin / awk

Java不是bash 。根据运行Java的操作系统,它要么不执行任何操作,要么不执行任何操作。最好假设Java不会做任何事情。 (此外,假设类似*.txt之类的东西将不起作用。在Windows中,它肯定会不起作用,而在Linux和Mac上肯定不起作用。将*.txt扩展到匹配的文件列表bash就是通配符。)

对于初学者,请勿使用Runtime.getRuntime()。exec()。始终使用ProcessBuilder,或者至少使用exec方法,该方法采用参数列表而不是单个字符串。然后,将以下内容作为命令行参数传递:

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变量进行的操作。

NB:看来您正在Windows内的某些Linux仿真层中运行事物,这肯定会使事情变得更复杂。