有没有一种复杂的方法来grep这个文件
is there a sophisticated way to grep this file
我有一个文件。用 BNF 写的可能是
<line>:== ((<ISBN10>|<ISBN13>)([a-Z/0-9]*)) {1,4})
例如
123456789X/abscd/1234567890123/djfkldsfjj
如何在每行中仅检索一个 ISBN10 或 ISBN13,即使该行中有更多 ISBN。如果行中有更多 ISBN,则应该只取行中的第一个。
当我这样 grep 时
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\).*//p" file
这与您的模式以及该行的其余部分相匹配,但只打印您的模式。然后您可以使用另一个实用程序来添加行号。例如。将您的输出通过管道传输到 nl -nrz -w9
.
好吧,假设提供的其他答案不正确,假设 'first' 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;'
我有一个文件。用 BNF 写的可能是
<line>:== ((<ISBN10>|<ISBN13>)([a-Z/0-9]*)) {1,4})
例如
123456789X/abscd/1234567890123/djfkldsfjj
如何在每行中仅检索一个 ISBN10 或 ISBN13,即使该行中有更多 ISBN。如果行中有更多 ISBN,则应该只取行中的第一个。
当我这样 grep 时
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\).*//p" file
这与您的模式以及该行的其余部分相匹配,但只打印您的模式。然后您可以使用另一个实用程序来添加行号。例如。将您的输出通过管道传输到 nl -nrz -w9
.
好吧,假设提供的其他答案不正确,假设 'first' 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;'