是否有任何grep / sed选项允许我在匹配其他模式后匹配模式?例如:输入文件(foo
s是以0
开头的变量模式,混合了前面带有#
的随机数字:
0foo1
0foo2
0foo3
\#89888
0foo4
0foo5
\#98980
0foo6
因此,一旦我尝试搜索变量模式(例如foo2
),我还想匹配此模式行号的另一个模式(例如#number
),在本例中为{ {1}}。
因此变量#89888
的输出必须是:
foo2
对于变量foo2 #89888
:
foo5
foo5 #98980
由每个字符组成,包括可被视为元字符的字符。
我使用tcl尝试了一个基本的正则表达式匹配脚本,它首先搜索foo
,然后搜索下一个立即foo*
,但由于我正在处理一个非常大的文件,所以需要几天时间完。任何帮助表示赞赏。
答案 0 :(得分:2)
Perl one-liner用于覆盖整个文件,并匹配您寻找的模式的任何换行符:
perl -000 -nle 'm{(foo2).*(\#89888)}s and print join " ",$1,$2' file
-000
开关启用" slurp"告知Perl不将文件拆分成块的模式,而是将其视为一个大字符串。 s
修饰符可让.
匹配任何字符,包括换行符。
答案 1 :(得分:0)
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my ( %matches, $recent_foo );
while(<DATA>)
{
chomp;
( $matches{$recent_foo} ) = $1 if m/(\\#\d+)/;
( $recent_foo ) = $1 if m/(0foo\d+)/;
}
print Dumper( \%matches );
__DATA__
0foo1
0foo2
0foo3
\#89888
0foo4
0foo5
\#98980
0foo6
./perl
$VAR1 = {
'0foo5' => '\\#98980',
'0foo3' => '\\#89888'
};
答案 2 :(得分:0)
如果你想要的是0foo1
,0foo2
和0foo3
都具有相同的值,则以下操作:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my ( %matches, @recent_foo );
while(<DATA>)
{
chomp;
if (/^\\#/)
{
@matches{@recent_foo} = ($') x @recent_foo;
undef @recent_foo;
}
elsif (/^0/)
{
push @recent_foo, $';
}
}
print Dumper( \%matches );
__DATA__
0foo1
0foo2
0foo3
\#89888
0foo4
0foo5
\#98980
0foo6
给出:
$VAR1 = {
'foo2' => '89888',
'foo1' => '89888',
'foo5' => '98980',
'foo3' => '89888',
'foo4' => '98980'
};
答案 3 :(得分:0)
Var='foo2'
sed "#n
/${Var}/,/#[0-9]\{1,\}/ {
H
/#[0-9]\{1,\}/ !d
s/.*//;x
s/.//;s/\n.*\\n/ /p
q
}" YourFile
不清楚请求。它首先出现你的模式 foo2 直到第一个 #number ,删除之间的行并打印出1行而不是退出(没有其他提取
答案 4 :(得分:0)
Tcl解决方案。该过程运行时间超过3微秒,因此您需要非常大型数据文件才能运行数天。如果多个令牌匹配,则使用第一个匹配(很容易重写该过程以返回所有匹配)。
set data {
0foo1
0foo2
0foo3
\#89888
0foo4
0foo5
\#98980
0foo6
}
proc find {data pattern} {
set idx [lsearch -regexp $data $pattern]
if {$idx >= 0} {
lrange $data $idx $idx+1
}
}
find $data 0foo3
# -> 0foo3 #89888
find $data 0f.*5
# -> 0foo5 #98980
答案 5 :(得分:0)
SED
<div class="navbar navbar-default">
<div class="navbar-inner">
<div class="container">
<div class="navbar-header">
<button type="button"
class="navbar-toggle"
data-toggle="collapse"
data-target="#myCollapseGuy">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a id="siteTitle" class="navbar-brand" href="/">Joseph Anthony King</a>
</div>
<div class="navbar-collapse collapse" id="myCollapseGuy">
<ul class="nav navbar-nav pull-right">
<li class="dropdown">
<a href="/">Home</a>
</li>
<li class="dropdown">
<a href="/Resume">Resume</a>
</li>
<li class="dropdown">
<a href="/Downloads">Downloads</a>
</li>
<li class="dropdown">
<a href="https://joe-king-sample-app.herokuapp.com/" target="_blank">
Sample App
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
sed -n '/foo2/,/#[0-9]\+/ {s/^[[:space:]]*[0\\]//; p}' file |
sed -n '1p; $p' |
paste -s
或0
。 AWK
\
TCL
awk -v p1=foo5 '
$0 ~ p1 {found = 1}
found && /#[0-9]+/ { sub(/^\\\/, ""); print p1, $0; exit }
' file
然后
lassign $argv filename pattern1
set found false
set fid [open $filename r]
while {[gets $fid line] != -1} {
if {[string match "*$pattern1*" $line]} {
set found true
}
if {$found && [regexp {#\d+} $line number]} {
puts "$pattern1 $number"
break
}
}
close $fid
答案 6 :(得分:0)
这是你想要的吗?
$ awk -v tgt="foo2" 'index($0,tgt){f=1} f&&/#[0-9]/{print tgt, $0; exit}' file
foo2 \#89888
$ awk -v tgt="foo5" 'index($0,tgt){f=1} f&&/#[0-9]/{print tgt, $0; exit}' file
foo5 \#98980
我在上面使用index()
,因为它搜索字符串而不是regexp,所以不必关心foo中的RE元字符是什么 - 它们都只是字符串中的文字字符。
如果你想在特定的foo之后找到一个特定的数字或foo2之后的第一个数字,或者你想要搜索特定的foo值或者所有&#34; foo& #34; s或......