复杂的正则表达式 - 在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>...))或字符转义(dws,...)。

如果你想使用[[ $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 中不起作用

非捕获组不在正则表达式中工作

正则表达式搜索 - 在测试人员中工作,而不是在Spyder中[重复]

正则表达式在在线正则表达式测试器中无法在Angular Validators.pattern()中工作