如何在两个固定字符串之间匹配不相关 charaters/blank-space 的模式?

How to match a pattern with unrelated charaters/blank-space between two fixed strings?

我正在尝试匹配文件中以 imports: [ 开头但不包含 SharedModule 的字符串。它可以在两个字符串之间有任何数字或 spaces、换行符或其他字符(单词)。我一直在努力寻找那些:

grep 'imports: \[[.*\s*]*SharedModule' */*.module.ts

但我什至找不到其中包含 'SharedModule' 的文件。我的想法是 .* 会找到任何单词,而 \s 会找到空白 space 字符,而带有 * 选择器的字符 class 将允许它以任何顺序显示。

  1. 我可以使用这样的字符 class 来跳过可变数量的无关 lines/characters 吗?
  2. 我如何否定语句所以 returns 行没有 'SharedModule'?
  3. 目标是将 'SharedModule' 追加到导入数组中尚不存在的地方。

谢谢! (我是新手,到目前为止我学到的一件事是:正则表达式很难)

样本匹配:

imports: [
  IonicPageModule.forChild(FormPage),
  DynamicFormComponentModule,
  SharedModule
],

不应该匹配但是

imports: [
  IonicPageModule.forChild(LeadershipPage),
],

应该。

grep 默认不处理多行字符串。这在 gnu grep-z 选项中可用,但正则表达式会有点复杂。

您最好使用带有自定义 RS(记录分隔符)的 gnu awk 解决方案:

awk -v RS='imports:[[:blank:]]*\[[^]]*\],[[:space:]]+' 'RT !~ /SharedModule/{ORS=RT} 1' file

imports: [
  IonicPageModule.forChild(LeadershipPage),
],

其中file内容是这样的:

cat file
imports: [
  IonicPageModule.forChild(FormPage),
  DynamicFormComponentModule,
  SharedModule
],

imports: [
  IonicPageModule.forChild(LeadershipPage),
],

有一个使用 grep 的解决方案 Pzo option for multiline support and negative lookahead:

grep -Pzo 'imports: \[(?:(?!SharedModule)[^]])*]'

这将 return 导入不包含 SharedModule 单词的语句。

您可以通过围绕它们使用一些编程逻辑来简化正则表达式要求。

这里有 POSIX awk:

$ awk '/\[/ {f=1} 
       f{s=s [=10=] ORS} 
       /\]/{if (index(s, "SharedModule")==0) print s; f=0; s=""}' file
imports: [
    IonicPageModule.forChild(LeadershipPage),
],

解释:

 /\[/ {f=1}             # if [ in line, set a flag
 f{s=s [=11=] ORS}          # if that flag is set, copy the input to the string s
 /\]/                   # closing ] in line
                        # print and reset
 {if ({if (index(s, "SharedModule")==0) print s; f=0; s=""}) print s; f=0; s=""}  

使用此文件:

$ cat file
imports: [
    IonicPageModule.forChild(FormPage),
    DynamicFormComponentModule,
    SharedModule
],

imports: [
    IonicPageModule.forChild(LeadershipPage),
],