【问题标题】:How to match a pattern with unrelated charaters/blank-space between two fixed strings?如何在两个固定字符串之间匹配具有不相关字符/空格的模式?
【发布时间】:2018-01-22 14:04:38
【问题描述】:

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

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

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

  1. 我可以使用这样的字符类来跳过数量不定的不相关行/字符吗?
  2. 如何否定该语句,使其返回没有“SharedModule”的行?
  3. 目标是将“SharedModule”附加到导入数组中不存在的位置。

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

样本匹配:

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

不应该匹配但是

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

应该。

【问题讨论】:

  • grep默认不是多行,检查stackoverflow.com/a/7167115/6320039
  • 我现在正在使用选项 -Zo,但只要我包含任何正则表达式,仍然没有找到结果。 -P 不识别?我在 Mac OS X 10.11.6

标签: regex grep multiline


【解决方案1】:

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),
],

【讨论】:

  • 太棒了!它似乎正在返回匹配的整个文件,而不仅仅是想要的行。是否会将此结果通过管道传递给添加“SharedModule”行的 sed 命令?
  • @ChrisSterbenz:你的 awk 版本是什么?正如我在回答中提到的,它需要gnu awk
  • 在 OSX 上,您可以使用 home brew 安装 gnu awk
【解决方案2】:

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

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

这将返回不包含 SharedModule 字的导入语句。

【讨论】:

    【解决方案3】:

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

    这里是 POSIX awk:

    $ awk '/\[/ {f=1} 
           f{s=s $0 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 $0 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),
    ],
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多