如何从文本文件中提取两个特定行之间的行?

时间:2019-11-06 12:40:17

标签: java

我有一个大文本文件,我想提取2条特定行之间的数据,我知道第一行和最后一行:

在模式中固定的第一行:“ <@@ ------注意流程信息->流程的调用栈:: [NLNOTES:43d8](时间16:06:56)----- -@@>“

以模式固定的最后一行:“ <@@ enter code here ------注意流程信息->为流程加载模块:: [ntaskldr:3e08](时间16:06:59) ------ @@>“

但是行数将与生成的日志一样多。

TEXT文件如下:

错误(4):无法附加到进程[安全系统:0048]-(5)访问被拒绝。

错误(4):无法附加到进程[注册表:0080]-(5)访问被拒绝。

错误(4):无法附加到进程[smss:01d0]-(5)访问被拒绝。

错误(4):无法附加到进程[csrss:0358]-(5)访问被拒绝。

错误(4):无法附加到进程[wininit:03c4]-(5)访问被拒绝。

<@@ ------注释流程信息->流程的调用栈:: [注释:43d8](时间16:06:56)------ @@>

1。错误(4):无法附加到进程[服务:017c]-(5)访问被拒绝。

2。错误(4):无法附加到进程[内存压缩:0c04]-(5)访问被拒绝。

3。错误(4):无法附加到进程[SecurityHealthService:1404]-(5)访问被拒绝。

4。错误(4):无法附加到进程[SgrmBroker:14f4]-(5)访问被拒绝。

5.ERROR(4):无法附加到进程[csrss:08d8]-(5)访问被拒绝。

<@@ ------注释过程信息->调用堆栈:: [注释:43d8](时间16:06:56)------ @@>

错误(4):无法附加到进程[内存压缩:0c04]-(5)访问被拒绝。

错误(4):无法附加到进程[SecurityHealthService:1404]-(5)访问被拒绝。

错误(4):无法附加到进程[SgrmBroker:14f4]-(5)访问被拒绝。

错误(4):无法附加到进程[csrss:08d8]-(5)访问被拒绝。

    public static void main(String[] args) {


    NLNOTES_Reader nl = new NLNOTES_Reader();
    String NLfile = "src/data.txt"; 

        try
        {   
            String[] lines = nl.readLines(NLfile);    

            for (String line : lines) 
            {
                if (line.contains("Call Stack for Process :: [ NLNOTES:"))
                     { 
                           System.out.println(line);                                                
                    }

            }
        }
        catch(IOException ie)
        {
            // Print out the exception that occurred
           System.out.println("Unable to create "+NLfile+": "+ie.getMessage());   
           ie.printStackTrace();
        }

}

1。错误(4):无法附加到进程[服务:017c]-(5)访问被拒绝。

2。错误(4):无法附加到进程[内存压缩:0c04]-(5)访问被拒绝。

3。错误(4):无法附加到进程[SecurityHealthService:1404]-(5)访问被拒绝。

4。错误(4):无法附加到进程[SgrmBroker:14f4]-(5)访问被拒绝。

5.ERROR(4):无法附加到进程[csrss:08d8]-(5)访问被拒绝。

2 个答案:

答案 0 :(得分:0)

使用流很容易做到这一点。您可以使用dropWhiletakeWhile方法。

如果文件中包含行的数组,则可以执行以下操作。

List<String> result = Arrays.stream(lines)
    .dropWhile(line -> !line.equals("first line"))
    .skip(1) // skip the start line
    .takeWhile(line -> !line.equals("last line"))
    .collect(Collectors.toList());

因此,您将获得2条特定行之间的所有行的列表(不包括那些特定行)。

此外,如果可以的话,最好使用BufferedReader在此处读取文件,因为它具有lines()方法,该方法返回文件中的行流。这样,您实际上就不必将整个文件存储在内存中。

List<String> result;
try (BufferedReader reader = new BufferedReader(new FileReader(NLfile))) {
    result = reader.lines()
        .dropWhile(line -> !line.equals("first line"))
        .skip(1) // skip the start line
        .takeWhile(line -> !line.equals("last line"))
        .collect(Collectors.toList());
} catch (IOException e) {
    System.out.println("Unable to create " + NLfile + ": " + ie.getMessage());   
    ie.printStackTrace();
}

更新:此解决方案仅适用于Java 9 +。

答案 1 :(得分:-1)

您说结尾行包含Notes Process Info -> Load Modules for Process,但我在您的文本文件中看不到它...

关于您提供的文本文件,只需使用以下代码:

        String NLfile = "src/data.txt";
        List<String> lines = new ArrayList<String>();

        try (BufferedReader br = new BufferedReader(new FileReader(NLfile))) {
            String line;
            boolean keepLine = false;

            while ((line = br.readLine()) != null) {

               //begin keeping lines in the result list
               if (line.contains("Call Stack for Process :: [ NLNOTES:")) {
                   keepLine = true;
                   continue;

               //exit while loop, no need to read the other lines
               } else if (line.contains("Call Stack :: [ NLNOTES:")) {
                   break;
               }

               //add the lines in the result list
               if (keepLine) {
                   lines.add(line);
               }
            }
        }
        catch(IOException ie)
        {
            // Print out the exception that occurred
           System.out.println("Unable to create "+NLfile+": "+ie.getMessage());   
           ie.printStackTrace();
        }