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

时间:2015-05-13 20:32:37

标签: grep

我有一个文件。写在BNF可能是

   123456789X/abscd/1234567890123/djfkldsfjj

例如

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

即使在行中有更多的ISBN,我怎样才能每行grep ISBN10或ISBN13一个。如果该行中有更多的ISBN,则应该只占第一行。

当我这样说的时候

$geoWithin

然后我获得了比原始文件更多的行。 (因为最多可以有4个ISBN)

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

有任何建议吗?

2 个答案:

答案 0 :(得分:1)

好吧,假设提供的其他答案不正确,假设“第一个”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中的行号,因此如果匹配,我们会打印该匹配项。 <>表示读取和迭代文件名或STDIN就像grep一样。所以你可以用与grep相似的方式调用它:

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;'

答案 1 :(得分:0)

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

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