是否有一种复杂的方法来grep这个文件

是否有一种复杂的方法来grep这个文件,grep,Grep,我有一个文件。用BNF写的,可能是 <line>:== ((<ISBN10>|<ISBN13>)([a-Z/0-9]*)) {1,4}) 我怎样才能在ISBN10或ISBN13中每行只显示一个,即使行中有更多的ISBN。如果行中有更多ISBN,则应只使用行中的第一个 当我往那边走的时候 grep -Po "[0-9]{9,13}X{0,1}" file 然后我得到了比文件原来更多的行。(因为一行最多有4个ISBN) 我还需要文件的行数应该是

我有一个文件。用BNF写的,可能是

 <line>:== ((<ISBN10>|<ISBN13>)([a-Z/0-9]*))  {1,4})
我怎样才能在ISBN10或ISBN13中每行只显示一个,即使行中有更多的ISBN。如果行中有更多ISBN,则应只使用行中的第一个

当我往那边走的时候

     grep -Po "[0-9]{9,13}X{0,1}" file 
然后我得到了比文件原来更多的行。(因为一行最多有4个ISBN)

我还需要文件的行数应该是grepresult的行数


有什么建议吗?

一个简单的解决方案是在正则表达式中包含行的开头:

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

好吧,假设提供的另一个答案不正确,假设“第一个”ISBN不在行的开头,您可以尝试使用perl

#!/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;
}
或:


谢谢,是的,第一个ISBN不需要在这行的开头,但我认为perl解决方案是正确的
#!/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 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;'