我想做模式匹配,以显示与以下结构匹配的文件中的文本部分。
## DN [Pattern-Matching] glob,regex
## Some text
## More text
## DN [Pattern-Matching] ends here的语法
## DN [TITLE] KEYWORD[,KEYWORD..]
## Some text
## More text
## DN [TITLE] ends here任何标题中的标题,带有关键字(由逗号分隔的多个关键字)。
要显示该部分,用户提供TITLE或KEYWORD。
以下列标签开始
lab="## DN [Something]"与我所做的上述模式相匹配的模式。
if [[ "$lab" =~ ^[[:space:]]*([#;!]+|@c|//)[[:space:]]DN[[:space:]]\[.*\]$ ]]; then现在我必须匹配额外的关键字部分。
在最后一部分中,我想要匹配keyword,keyword
我已经开始用([^,]+)做这个了。我的困惑是在那之后匹配零或更多,keyword的剩余可能性。
发布于 2023-01-30 09:28:35
使用awk或perl进行文本处理,而不是bash。
例如使用awk:
awk '/^[[:blank:]]*##[[:blank:]]+DN[[:blank:]]+\[TITLE\]/ {
if (p) print;
p = ! p
};
p' input.txt
## DN [TITLE] KEYWORD[,KEYWORD..]
## Some text
## More text
## DN [TITLE] ends here顺便说一句,如果您不熟悉awk,在awk脚本中的分号之后的最后一个p将测试p是否为真,如果D2为真,则打印当前行--这相当于{if (p) print}。简而言之: awk脚本由一系列“模式操作”规则组成,可以省略模式或操作。模式是计算为真或假的任何东西。如果省略了该模式,默认的计算结果为true (即该操作将始终被执行)。动作是要执行的awk代码。如果省略该操作,则默认为print。
或者使用perl:
$ perl -ne 'if (/^\h*##\h+DN\h+\[TITLE\]/) {
print if $p;
$p = ! $p
};
print if $p' input.txt
## DN [TITLE] KEYWORD[,KEYWORD..]
## Some text
## More text
## DN [TITLE] ends here这两个脚本的工作原理是一致的--它们是彼此的直接翻译。
在这两个脚本中,变量p ($p for perl)被用作切换,每当看到模式时都会打开或关闭打印。
这两个脚本都需要少量的代码复制。切换p (或$p)的代码块必须检查p是否为真,并在切换p之前打印。否则,您想要的块的最后一行将不会被打印出来,因为在执行“printed为true”测试之前,p已经关闭。
注意:[[:blank:]]表示空格或制表符。perl的\h意味着<#>任何水平空格(包括一些unicode空格字符,取决于地区)。实际上,这两种方法对于ASCII文本都是一样的。
如果您需要测试两个条件,那么使用两个变量--比如p1和p2 ($p1和$p2 for perl)。单独测试它们,并且只打印两者都是正确的:例如,p1 && p2中的awk,print if ($p1 && $p2)中的perl。
Shell变量可以通过命令行传递到awk或perl,也可以通过环境变量传递(export是bash中的一个变量,它将在所有子进程的环境中可用)。
https://unix.stackexchange.com/questions/733668
复制相似问题