是否有一种复杂的方法来抓取此文件



我有一个文件。用BNF写成

 <line>:== ((<ISBN10>|<ISBN13>)([a-Z/0-9]*))  {1,4})

例如

   123456789X/abscd/1234567890123/djfkldsfjj

即使在行中有更多的ISBN,我如何才能将ISBN10或ISBN13抓住。如果行中有更多的ISBN,则只需排在第一个。

当我以这种方式抓住时

     grep -Po "[0-9]{9,13}X{0,1}" file 

然后,我得到的线比最初的文件还要多。(因为在线可能有最大4个ISBN)

我还需要文件的linecount是grepresult的linecount。

有什么建议?

好吧,假设提供的另一个答案是假设'第一个'ISBN不在行开始时不正确的,那么您可以随时尝试。

#!/usr/bin/perl
use strict;
use warnings;
while (<>) {
    chomp;
    my ( $first_isbn, @rest ) = m/(d{9,13}X{0,1})/g;
    print $., ":", $first_isbn, "n" if $first_isbn;
}

$.是perl中的行号,因此,如果有匹配项,我们将其打印和匹配。 <>像格雷普一样,读取并迭代文件名或stdin。因此,您可以以类似的方式调用此内容:

perl myscript.pl <filename>

或:

cat <filename> | ./myscript.pl 

这将单线形式为:

perl -lne 'my ( $first_isbn ) = m/(d{9,13}X{0,1})/g; print $., ":", $first_isbn, "n" if $first_isbn;'

一个微不足道的解决方案是将行的开始包括在您的正则:

grep -Po "^[0-9]{9,13}X{0,1}" file

这可以确保第一个之后与之匹配的匹配不满意。似乎是从您的BNF来看,如果存在的ISBN可以保证是该行的第一个字符。

另一种方法是使用sed:

 sed -n "s/([0-9]{9,13}X).*/1/p" file

这与您的图案与线路的其余部分匹配,但只能打印出您的图案。然后,您可以使用另一个实用程序添加行号。例如。将输出输出到nl -nrz -w9

最新更新