如何在两个固定字符串之间匹配不相关 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 将允许它以任何顺序显示。
- 我可以使用这样的字符 class 来跳过可变数量的无关 lines/characters 吗?
- 我如何否定语句所以 returns 行没有 'SharedModule'?
- 目标是将 '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),
],
我正在尝试匹配文件中以 imports: [
开头但不包含 SharedModule
的字符串。它可以在两个字符串之间有任何数字或 spaces、换行符或其他字符(单词)。我一直在努力寻找那些:
grep 'imports: \[[.*\s*]*SharedModule' */*.module.ts
但我什至找不到其中包含 'SharedModule' 的文件。我的想法是 .* 会找到任何单词,而 \s 会找到空白 space 字符,而带有 * 选择器的字符 class 将允许它以任何顺序显示。
- 我可以使用这样的字符 class 来跳过可变数量的无关 lines/characters 吗?
- 我如何否定语句所以 returns 行没有 'SharedModule'?
- 目标是将 '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),
],