复杂的正则表达式 - 在Powershell中工作,而不是在Bash中工作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复杂的正则表达式 - 在Powershell中工作,而不是在Bash中工作相关的知识,希望对你有一定的参考价值。
下面的代码是我的代码的一小部分,用于解析Netbackup命令的输出。这适用于我们的Windows机箱,但我们的一些机箱是RHEL。
我正在尝试将下面的代码转换为RHEL 4.X上可用的东西,但我正在解析正则表达式。显然下面的代码有一些转义为与Powershell一起使用的字符,我没有将这些字符用于Shell。
我还不熟悉Shell,但我会在Powershell代码下面发布一部分Shell代码。
$output = ./bpdbjobs
$Results = @()
$ColumnName = @()
foreach ($match in $OUTPUT) {
$matches = $null
$match -match "(?<jobID>d+)?s+(?<Type>([^dW]+)|([^dW]+s+[^dW]+))?s+(?<State>(Done)|(Active)|(w+`-w+`-w+))?s+(?<Status>d+)?s+(?<Policy>(w+)|(w+`_w+)|(w+`_w+`_w+))?s+(?<Schedule>([^dW]+-[^dW]+)|(-)|([^dW]+))?s+(?<Client>(w+.w+.w+)|(w+))?s+(?<Dest_Media_Svr>(w+.w+.w+)|(w+))?s+(?<Active_PID>d+)?s+(?<FATPipe>[^dW]+)?"
$Results+=$matches
}
下面是我编写的Shell代码的一小部分(这显然是非常错误的,我在这里学习)。我只是用它来测试Regex,看看它是否在Shell中运行 - (Spoiler alert)它没有。
#!/bin/bash
#
backups=bpdbjobs
results=()
for results in $backups; do
[[ $results =~ /(?<jobID>d+)?s+(?<Type>([^dW]+)|([^dW]+s+[^dW]+))?s+(?<State>(Done)|(Active)|(w+w+-w-+))?s+(?<Status>d+)?s+(?<Policy>(w+)|(w+\_w+)|(w+\_w+\_w+))?s+(?<Schedule>([^dW]+-[^dW]+)|(-)|([^dW]+))?s+(?<Client>(w+.w+.w+)|(w+))?s+(?<Dest_Media_Svr>(w+.w+.w+)|(w+))?s+(?<Active_PID>d+)?/ ]]
done
$results
以下是我得到的错误。
./netbackupsolarwinds.sh: line 9: syntax error in conditional expression: unexpected token `('
./netbackupsolarwinds.sh: line 9: syntax error near `/(?'
./netbackupsolarwinds.sh: line 9: ` [[ $results =~ /(?<jobID>d+)?s+(?<Type>([^dW]+)|([^dW]+s+[^dW]+))?s+(?<State>(Done)|(Active)|(w+w+-w-+))?s+(?<Status>d+)?s+(?<Policy>(w+)|(w+\_w+)|(w+\_w+\_w+))?s+(?<Schedule>([^dW]+-[^dW]+)|(-)|([^dW]+))?s+(?<Client>(w+.w+.w+)|(w+))?s+(?<Dest_Media_Svr>(w+.w+.w+)|(w+))?s+(?<Active_PID>d+)?/ ]]'
来自man bash
:
可以使用另一个二元运算符=〜,其优先级与==和!=相同。使用它时,操作符右侧的字符串被视为扩展正则表达式并相应地匹配(如regex(3)中所示)。
这意味着表达式被解析为POSIX扩展正则表达式,AFAIK不支持命名捕获组((?<name>...)
)或字符转义(d
,w
,s
,...)。
如果你想使用[[ $var =~ expr ]]
,你需要重写正则表达式。否则使用grep
(支持PCRE):
grep -P '(?<jobID>d+)?s+...' <<<$results
更新后的答案,更新后的答案。
快速执行迁移的最佳方法是使用Grep的--perl-regexp Perl兼容性选项,如最终在另一个答案中建议的那样。
如果您仍想使用纯Bash执行此操作,则需要在the documentation之后相应地重写正则表达式。
谢谢大家的答案。我交换到Grep -P无济于事,原来命名的捕获组是Grep -P的问题。
我也无法找到一种方法来使用Grep将捕获组匹配输出到单个变量。
这导致我交换使用perl,如下所示,改变我的正则表达式。
bpdbjobs | perl -lne 'print "$1" if /(d+)?s+(([^dW]+)|([^dW]+s+[^dW]+))?s+((Done)|(Active)|(w+w+-w-+))?s+(d+)?s+((w+)|(w+\_w+)|(w+\_w+\_w+))?s+((b[^dW]+-[^dW]+)|(-)|([^dW]+))?s+((w+.w+.w+)|(w+))?s+((w+.w+.w+)|(w+))?s+(d+)?/g'
$<num>
指的是捕获组编号。我现在可以列出,显示和(重要部分)计算单个组内的匹配数,对应于每列中找到的数据。
以上是关于复杂的正则表达式 - 在Powershell中工作,而不是在Bash中工作的主要内容,如果未能解决你的问题,请参考以下文章
Robotframework - 在python中工作的正则表达式不匹配
正则表达式在文本编辑器(崇高)中工作,但在 python 中不工作 [重复]
在在线正则表达式测试器中工作的 MariaDB 正则表达式在 SELECT WHERE REGEXP 中不起作用