使用Awk和Grep,我需要打印一些行

时间:2018-11-30 11:54:49

标签: bash perl awk grep

我在编写Perl脚本时比较新鲜,所以我想以此作为问题或对此的支持,下面是代码

start pattern1

line1
Matching pattern can be here
line2
Matching Pattern can be here
line3
line4
...
end pattern1
.
start pattern1
line1
line2
start pattern1

start pattern1
line1
Matching pattern can be here
line2
start pattern1

所以从perl中,我需要grep开始模式1 ...结束模式1之间的行, 为此,我正在使用awk命令进行grep

 $cmd = q(awk '/start pattern1/,end pattern1 /' x.file );
 $n1 = system($cmd);

此输出正常工作,下面是输出,

start pattern1
line1
**Matching pattern can be here**
line2
**Matching Pattern can be here**
...
end pattern1

但是在文件中,我有1000行这样的行,因此我需要grep具有匹配模式的行。即我只需要grep那些开始的模式行到结束的模式行具有匹配的模式

为此,我尝试了

 $cmd = q(awk '/start pattern1/,end pattern1 /' x.file | grep  '$n2\|line4');
 $n1 = system($cmd);

但是当我使用上述命令时,我看不到任何输出 $ n2包含一些从另一个文件中提取的模式。

如果我使用直接匹配的模式代替$ n2可以正常工作,为什么我不能在这里使用$ n2?

注意:我正在perl脚本中使用它

从Awk命令中,我获得了起始pattern1 ... end pattern1之间的所有行,但是我有1000个这样的打印件,因此我需要从start pattern1到thos结束pattern1的那一行与匹配模式

我做的时候的预期输出是

start pattern1
line1
Matching pattern can be here
line2
Matching Pattern can be here
line3
line4
...
end pattern1 

 start pattern1
    line1
    Matching pattern can be here
    line2
    start pattern1

1 个答案:

答案 0 :(得分:2)

由于perl比awk强大得多,因此无需从perl内召唤awk。

我不清楚是否要在start pattern1end pattern1之间的每行,如果里面至少有一个匹配项,或者是 just 匹配的行。

如果开始和结束之间的每一行都匹配:

my @blocks = join("",<>)=~/start pattern1\s*(.*?)end pattern1/gsi;
print grep /matching pattern/i, @blocks;

如果每一行都包含开始|结束模式1:

my @blocks = join("",<>)=~/(start pattern1.*?end pattern1\s*)/gsi;

如果只是在开始和结束之间使用/ matching pattern /的行:

print grep { /start pattern1/i../end pattern1/i and /matching pattern/i } <>;

将其放入文件program.pl并运行:

perl program.pl inputfile > outputfile

可能需要一些解释:join("",<>)将整个输入文件作为一个多行字符串返回。 /gsi修饰符的含义是:g全局匹配,以便@block数组将包含括号所匹配的内容,每个匹配项包含一个数组元素(不包含g { 1}}数组只会得到第一行代码,@block意味着s也匹配换行符,否则它将不匹配,而.通过忽略大小写进行匹配(看不到区别)在AZ和AZ字母之间)。 i中的问号表示每个字符都没有贪婪匹配,也就是说,匹配直到 next .*?而不是最后一个字符。 end pattern1<>的行({{1}之后的参数)作为字符串数组返回。 inputfile是触发器运算符,在左侧变为true之后为true,在右侧变为true之后为false,并保持为false,直到左侧再次变为true,依此类推。