文件搜索和邻近搜索
File searching and proximity search
我一直在看grep a file, but show several surrounding lines?
我正在使用 bash 终端,正在寻找一个文件
在任何一行上都有 path
和 redirect
在附近的一行上有 flash
,距离第一行不到五行
这可能与 grep、ag、Perl、sed 或你们知道的任何工具有关吗?
带有 "flash" 的过滤器更简单。先做也好,这样比较昂贵的模式匹配就在匹配文件的子集中完成。
为此,只需说:
grep -RH -C 5 "text" *
这将递归地 (-R
) 查找模式 "text" 并在发生这种情况时打印文件名 (-H
)。此外,它将打印周围的 5 行 (-C 5
)。如果需要,只需将 5
更改为变量即可。
那么是时候使用 awk 检查两个模式了:
awk '/pattern1/ && /pattern2/ {print FILENAME}' file
这很有用 awk is quite good on multiple patterns matching。
由于我们没有文件名,而是形式为 filename:flash
的流,因此我们可以有一个基本的 Bash 循环来处理来自 grep
的结果:
while IFS=":" read -r filename data;
do
awk -v f="$filename" '/path/ && /redirect/ {print f}' <<< "$data"
done < <(grep -RH -C5 "text" *)
这比看起来要复杂一些,因为您要查找的是大致相近的单词。
所以我可能会这样处理它:
#!/usr/bin/env perl
use strict;
use warnings;
my $buffer_limit = 5; # +/- 5
my @buffer;
my $first_flag;
my $second_flag;
#iterate stdin or files specified on command line
while ( my $line = <> ) {
#test first condition
if ( $line =~ m/path/ and $line =~ m/redirect/ ) { $first_flag++; };
#test second condition
if ( $line =~ m/flash/ ) { $second_flag++; };
#if either is true - match has been seen recently.
#save the line in the buffer.
if ( $first_flag or $second_flag ) {
push @buffer, $line
}
#if both are true, we print (and flush the buffer)
if ( $first_flag and $second_flag ) {
print "Match found up to line $.:\n";
print @buffer;
@buffer = ();
$first_flag = 0;
$second_flag = 0;
}
#exceeding limit means that both matches haven't been seen in proximity.
if ( @buffer > $buffer_limit ) {
@buffer = ();
$first_flag = 0;
$second_flag = 0;
}
}
我们使用滚动的 5 行缓冲区。当我们命中一个或另一个 'match' 时我们开始捕获,如果我们命中第二个匹配项我们 print/flush 。如果超过 5 行,则清空缓冲区。
ack -A6 -B4 'path.*redirect|redirect.*path' FILES | grep flash
在文件 FILES
中包含模式 path
和 redirect
的行之前的 4 行或之后的 6 行中输出包含模式 flash
的行连同文件名和包含 flash
.
的行的行号
如果没有 ack
命令(或 egrep
命令,也可以),您可以将其改写为两个 grep
命令
(grep -A6 -B4 'path.*redirect' FILES ; grep -A6 -B4 'redirect.*path' FILES) |
grep flash
我一直在看grep a file, but show several surrounding lines?
我正在使用 bash 终端,正在寻找一个文件
在任何一行上都有
path
和redirect
在附近的一行上有
flash
,距离第一行不到五行
这可能与 grep、ag、Perl、sed 或你们知道的任何工具有关吗?
带有 "flash" 的过滤器更简单。先做也好,这样比较昂贵的模式匹配就在匹配文件的子集中完成。
为此,只需说:
grep -RH -C 5 "text" *
这将递归地 (-R
) 查找模式 "text" 并在发生这种情况时打印文件名 (-H
)。此外,它将打印周围的 5 行 (-C 5
)。如果需要,只需将 5
更改为变量即可。
那么是时候使用 awk 检查两个模式了:
awk '/pattern1/ && /pattern2/ {print FILENAME}' file
这很有用 awk is quite good on multiple patterns matching。
由于我们没有文件名,而是形式为 filename:flash
的流,因此我们可以有一个基本的 Bash 循环来处理来自 grep
的结果:
while IFS=":" read -r filename data;
do
awk -v f="$filename" '/path/ && /redirect/ {print f}' <<< "$data"
done < <(grep -RH -C5 "text" *)
这比看起来要复杂一些,因为您要查找的是大致相近的单词。
所以我可能会这样处理它:
#!/usr/bin/env perl
use strict;
use warnings;
my $buffer_limit = 5; # +/- 5
my @buffer;
my $first_flag;
my $second_flag;
#iterate stdin or files specified on command line
while ( my $line = <> ) {
#test first condition
if ( $line =~ m/path/ and $line =~ m/redirect/ ) { $first_flag++; };
#test second condition
if ( $line =~ m/flash/ ) { $second_flag++; };
#if either is true - match has been seen recently.
#save the line in the buffer.
if ( $first_flag or $second_flag ) {
push @buffer, $line
}
#if both are true, we print (and flush the buffer)
if ( $first_flag and $second_flag ) {
print "Match found up to line $.:\n";
print @buffer;
@buffer = ();
$first_flag = 0;
$second_flag = 0;
}
#exceeding limit means that both matches haven't been seen in proximity.
if ( @buffer > $buffer_limit ) {
@buffer = ();
$first_flag = 0;
$second_flag = 0;
}
}
我们使用滚动的 5 行缓冲区。当我们命中一个或另一个 'match' 时我们开始捕获,如果我们命中第二个匹配项我们 print/flush 。如果超过 5 行,则清空缓冲区。
ack -A6 -B4 'path.*redirect|redirect.*path' FILES | grep flash
在文件 FILES
中包含模式 path
和 redirect
的行之前的 4 行或之后的 6 行中输出包含模式 flash
的行连同文件名和包含 flash
.
如果没有 ack
命令(或 egrep
命令,也可以),您可以将其改写为两个 grep
命令
(grep -A6 -B4 'path.*redirect' FILES ; grep -A6 -B4 'redirect.*path' FILES) |
grep flash