2017-09-10 66 views
0

我不知道为什么这不起作用。这里是正则表达式'text\' => '.*?',我想用grep或sed在以下恶意文本中捕获estrenoscine。这是我在grep上试过的将正则表达式转换为sed或grep正则表达式

echo "sadsa d{        'text' => 'cine',        'indices' => [           111,           116           ]       },       {        'text' => 'estrenos',        'indices' => [ sSADW" | grep -Eo "'text\' => '.*?'," 

回答

3

只需使用AWK:

$ awk -v RS='}' -F\' '{print $4}' file 
cine 
estrenos 

这将在任何外壳采用任何AWK上工作任何UNIX框。无论白色空间是什么,它都可以工作,因此无论您的输入是在一行上还是在多行上传播,无论每行上的任何位置出现多少空白或制表符,它都可以工作。

下面是它如何工作的:

AWK将所有输入作为分隔成字段的记录。您的输入(与空间压缩的可读性):

sadsa d{ 'text' => 'cine', 'indices' => [ 111, 116 ] }, { 'text' => 'estrenos', 'indices' => [ sSADW 

显然有{ ... }记录:

记录1:

{ 'text' => 'cine', 'indices' => [ 111, 116 ] } 

记录2:

{ 'text' => 'estrenos', 'indices' => [ sSADW 

,所以我们可以设置记录分隔符为}(与-v RS='}')。我假设你的最后一个记录也会在}之内结束,但是如果它没那么好,awk会像记录结束一样处理文件结尾。我们可以忽略{之前的文本(即第一条记录之前的“sadsa d”和2条记录之间的“,”,这些文本被视为第一个字段的一部分,但我们并未使用该字段来处理任何事情,因此它无关紧要。

因此,考虑上述2条记录,如果我们他们在每一个'分成字段(-F\'),那么我们得到:

$ awk -v RS='}' -F\' '{for (i=1; i<=NF;i++) print "Record Nr", NR, "Field Nr", i, "Field Contents: <" $i ">"; print "----" 
}' file 
Record Nr 1 Field Nr 1 Field Contents: <sadsa d{ > 
Record Nr 1 Field Nr 2 Field Contents: <text> 
Record Nr 1 Field Nr 3 Field Contents: < => > 
Record Nr 1 Field Nr 4 Field Contents: <cine> 
Record Nr 1 Field Nr 5 Field Contents: <, > 
Record Nr 1 Field Nr 6 Field Contents: <indices> 
Record Nr 1 Field Nr 7 Field Contents: < => [ 111, 116 ] > 
---- 
Record Nr 2 Field Nr 1 Field Contents: <, { > 
Record Nr 2 Field Nr 2 Field Contents: <text> 
Record Nr 2 Field Nr 3 Field Contents: < => > 
Record Nr 2 Field Nr 4 Field Contents: <estrenos> 
Record Nr 2 Field Nr 5 Field Contents: <, > 
Record Nr 2 Field Nr 6 Field Contents: <indices> 
Record Nr 2 Field Nr 7 Field Contents: < => [ sSADW 
> 
---- 

所以你可以看到你想要的值总是简单的第四场

+0

你能把它分解吗? – user3639557

+1

我添加了一个解释,让我知道如果您有任何问题。 –

+1

地狱的解释。太好了。而埃德,你不认为使用扩展grep也是一个不错的选择,因为grep主要是为了这个目的。这里例如。 'egrep -o''text'=>'\ w +'“file | cut -d'-f4'?如果不是,为什么? – batMan

0

删除单引号的转义字符。然而,由于扩展的正则表达式不支持非贪婪的匹配你可能想使用Perl来代替:

grep -Po "'text' => '.*?', 
+0

不错!但是,这会返回''text'=>'cine'',但我想要''cine' – user3639557

+1

@ user3639557您可以将其修改为'grep -Po''text'=>'\ K [^'] +“ ''或'grep -Po''text'=>'\ K [^'] +(?=',)“'为了健壮性 – Sundeep

+0

您应该提及那只是GNU grep,根据GNU grep手册页'-P '是“高度实验性的”,因此YMMV使用它。 –

0

tr + sed的方法:

(假设你输入的文本是可变$s

sed -n "s/.*'text' => '\([^']*\)'.*/\1/p" <(tr ',' '\n' <<< "$s") 

输出:

cine 
estrenos