如何在两个固定字符串之间匹配具有无关字符/空格的模式?
如何在两个固定字符串之间匹配具有无关字符/空格的模式?
我正在尝试在我的文件中匹配一个以imports: [
开头且不包含SharedModule
的字符串。在这两个字符串之间可以有任意数量的空格、换行符或其他字符(单词)。我一直在尝试使用以下命令来查找这些内容:
grep 'imports: \[[.*\s*]*SharedModule' */*.module.ts
但是我甚至找不到包含'SharedModule'的文件。我的思路是.*可以匹配任意单词,\s可以匹配空格字符,而带有*选择器的字符类可以让它们以任意顺序出现。
- 我能否使用这样的字符类来跳过不相关的行/字符?
- 如何取反语句以返回不包含'SharedModule'的行?
- 目标是将'SharedModule'附加到导入数组中,无论其是否已存在。
谢谢!(我对此还不熟悉,迄今为止我学到的一件事是:正则表达式很难)
示例匹配:
imports: [ IonicPageModule.forChild(FormPage), DynamicFormComponentModule, SharedModule ],
不应匹配,但
imports: [ IonicPageModule.forChild(LeadershipPage), ],
应该匹配。
正文:
问题:如何在两个固定字符串之间的无关字符/空格中匹配一个模式?
在处理这个问题时,可以通过在正则表达式周围使用一些编程逻辑来简化匹配要求。下面是使用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} # 如果行中有[,设置标志
f{s=s $0 ORS} # 如果标志已设置,将输入复制到字符串s
/\]/ # 行中有闭合的]
# 打印并重置
{if (index(s, "SharedModule")==0) print s; f=0; s=""}
使用以下文件作为示例:
$ cat file imports: [ IonicPageModule.forChild(FormPage), DynamicFormComponentModule, SharedModule ], imports: [ IonicPageModule.forChild(LeadershipPage), ],
根据这个问题的描述和解决方法,我们可以得出以下结论:
问题的原因是需要在两个固定字符串之间的无关字符/空格中匹配一个模式。为了解决这个问题,我们可以使用编程逻辑来简化匹配要求。在给定的示例中,我们使用了POSIX awk来实现这一点。首先,我们设置一个标志f,当行中出现[时,将其设置为1。然后,如果标志f已设置,我们将输入复制到字符串s。当行中出现]时,我们检查字符串s中是否包含"SharedModule",如果不包含,则打印字符串s,并重置标志f和字符串s。通过这种方式,我们成功地在两个固定字符串之间的无关字符/空格中匹配了一个模式。
问题的出现原因是grep默认不处理多行字符串。可以使用gnu grep的-z选项来处理多行字符串,但是正则表达式会变得更复杂一些。可以使用gnu awk的解决方案,使用自定义的RS(记录分隔符)来实现。文件的内容如下:
imports: [ IonicPageModule.forChild(FormPage), DynamicFormComponentModule, SharedModule ], imports: [ IonicPageModule.forChild(LeadershipPage), ],
可以运行以下命令:
awk -v RS='imports:[[:blank:]]*\\[[^]]*\\],[[:space:]]+' 'RT !~ /SharedModule/{ORS=RT} 1' file
这将返回整个匹配的文件内容,而不仅仅是所需的行。可以通过将结果传递给sed命令来添加“SharedModule”行。
如果你的awk版本是什么?如我在我的答案中提到的,它需要gnu awk。在OSX上,可以使用home brew来安装gnu awk。