【问题标题】:Perl: How do I read a text file word by word starting at a particular pattern?Perl:如何从特定模式开始逐字阅读文本文件?
【发布时间】:2015-08-08 00:31:40
【问题描述】:

我正在尝试编写一个脚本来读取以空格分隔的文本文件并识别特定模式PATTERN。识别PATTERN 后,脚本应读取RANDOM_NUMBER 的以PATTERN 开头的单词。例如,假设PATTERNa 并且RANDOM_NUMBER7。那么对于这个文本文件:

1 2 3 4 5 6
a b c d e f 
g h i j k j

我想得到:

a b c d e f
g

作为输出。

到目前为止,我已经能够识别这些模式,但我不知道以后如何处理它。阅读单词的最佳方法是什么?

顺便说一句,我查看了Read text file in Perl word by word instead of line by line,这对我的目的来说有点太模糊了。此外,就代码的作用而言,答案并没有提供太多解释。

【问题讨论】:

  • 您可以将整个文件读入字符串缓冲区,然后使用正则表达式将其拆分为单词

标签: perl parsing


【解决方案1】:

好的,所以这里的技巧是设置$/ - 记录分隔符。如果我们将其设置为' ',我们可以一次迭代一个“单词”。

然后我们可以使用范围运算符来“检测”我们是否在我们的模式之间。

local $/ = ' ';

while ( <DATA> ) {
    if ( m/a/ ..  10 ) { print; }
}

现在,这会将 from a 打印到“字段 10” - 这并不是特别有用,因为“计数”从文件的开头开始。 (由

因此,我们可能希望在所见条件为真时“触发”,并继续进行许多其他迭代:

#!/usr/bin/perl
use strict;
use warnings;

local $/ = ' ';

while (<DATA>) {
    if (m/a/) {
        print;
        for ( 2 .. 7 ) { print scalar <DATA>; } #2 because we already have "1"
        last; #assuming we only want to do this once. 
    }
}


__DATA__
1 2 3 4 5 6 
a b c d e f 
g h i j k j

哪些打印:

a b c d e f 
g 

【讨论】:

  • 好吧,假设我的文件很大——从头开始逐字阅读会不会很慢?有没有办法逐行阅读,直到找到模式,然后逐字阅读?另外,您能否澄清“继续进行其他多次迭代”的意思? for (1 .. 7) { print scalar &lt;DATA&gt;; } 不会也从文件的开头开始吗?谢谢!
  • 输入是缓冲的,所以这是一个有争议的问题。从磁盘读取的实际数据是更大的块。但是你可以在模式匹配之后设置$/ - 怀疑它会产生很大的不同。请记住,您已经阅读了整行 a b c d e f。阅读&lt;DATA&gt; 从上次停止的地方继续。
  • 也许sysread 可以用来绕过缓冲?
  • 你为什么要这样做?
  • 缓冲是件好事。您一次至少从磁盘读取一个扇区,并且可能是 1k 块。这意味着无论您的脚本是“读取”一个字节还是一行,它都是相同数量的 IO 操作。
猜你喜欢
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
  • 2017-04-11
  • 2017-09-13
相关资源
最近更新 更多