【问题标题】:With Awk and Grep i need to print some lines使用 awk 和 Grep 我需要打印一些行
【发布时间】:2019-05-02 13:56:59
【问题描述】:

我在编写 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 命令中,我得到了起始模式 1...结束模式 1 之间的所有行,但我有 1000 个这样的打印,所以我需要开始模式 1 的行到结束模式 1 的匹配匹配模式

我这样做时的预期输出是,

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

【问题讨论】:

  • 如果您尝试在 perl 脚本中执行此操作,则无需使用 awk 或 grep。只需使用内置的 perl 功能。
  • @RamCharan,cmets 不是为了解释问题,请用适当的细节更新您的问题,然后让我们知道。
  • 你问的问题的答案是q() 不插入变量,但是整个代码很糟糕,应该扔掉。
  • @RamCharan 如果你需要更新一个 perl 脚本,你需要学习 perl。仅仅因为您不知道语法而从任何语言调用 system() 都是不好的做法。
  • awk | grep 是一种反模式。在 perl 中调用 awk 是一种反模式。在 perl 中调用 awk 管道到 grep 是反物质的,可能会导致已知宇宙的破坏。

标签: bash perl awk grep


【解决方案1】:

不需要从 perl 中调用 awk,因为 perl 比 awk 强大得多。

如果内部至少有一个匹配项,我不清楚您是否需要 每一行 start pattern1end pattern1 之间的行,或者 匹配行。

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

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("",&lt;&gt;) 将整个输入文件作为一个多行字符串返回。 /gsi 修饰符意味着:g 全局匹配,因此 @block 数组将包含括号匹配的内容,每个匹配项都有一个数组元素(没有 g @block 数组将只获得第一个块行数),s 表示 . 也匹配换行符,否则它不会匹配,i 通过忽略大小写匹配(看到 az 和 AZ 字母之间没有区别)。 .*? 中的问号表示对每个字符进行非贪婪匹配,即匹配到下一个 end pattern1 而不是最后一个。 &lt;&gt;inputfile 的行(perl program.pl 之后的参数)作为字符串数组返回。 .. 是触发器运算符,左侧为真后为真,右侧为真后为假,直到左侧再次为真,以此类推。

【讨论】:

  • 感谢 Kjetil 提供的非常有用的信息,另外还有 1 个查询不是从命令行传递输入文件,我们可以在上面的代码中编程吗??
  • @RCV → 是的,只需在第一行添加open my $fh, "filename.txt" or die;。然后将&lt;&gt; 替换为&lt;$fh&gt;。 (fh 是文件句柄的缩写)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-17
  • 2017-09-27
  • 1970-01-01
  • 1970-01-01
  • 2017-04-13
  • 2012-09-24
相关资源
最近更新 更多