As ferramentas tradicionais unix suportam BRE ou ERE (expressões regulares básicas ou estendidas). POSIX codifica ambos. Wikipedia explica-os. A maioria das ferramentas modernas estende ERE, muitas vezes com recursos adicionais introduzidos pela primeira vez em Perl (que é conhecido como PCRE ).
O ERE estende a funcionalidade do BRE, mas não estende a sintaxe. No BRE, apenas os caracteres \[.*^$
têm um significado especial e alguns operadores, como o agrupamento \(…\)
, usam barras invertidas. No ERE, +?|()
também são especiais, e a barra invertida seguida por um caractere não alfanumérico nunca é especial.
O BRE não tem \d
e \s
do Python / PCRE. Você pode expressar esses conjuntos de caracteres com construções de conjuntos tradicionais e classes de caracteres: \d
is [[:digit:]]
e \s
is [[:space:]]
. Observe os colchetes duplos: um para indicar um conjunto de caracteres e outro para indicar uma classe de caractere; por exemplo, "letras, traços ou sublinhados" podem ser escritos [-_[:alpha:]]
.
O BRE não tem um operador +
(algumas implementações de sed suportam \+
como extensão da sintaxe BRE); X+
é o mesmo que XX*
. Os grupos e as correspondências precisam de barras invertidas adicionais.
O equivalente a BRE do \s+ up \s+(\d{1,2}):(\d{1,2})
do Python é, portanto, [[:space:]][[:space:]]* up [[:space:]][[:space:]]*\([[:digit:]]\{1,2\}\):\([[:digit:]]\{1,2\}\)
. Observe que você está combinando muito espaço em branco: \s+
e um espaço significa pelo menos dois caracteres em branco.
Você precisará corresponder à linha inteira, pois o comando s
do sed reconfigura a linha. Não há um comando separado para escrever uma string montada a partir de grupos salvos. Corrigindo o espaço em branco extra, o análogo do seu snippet do Python é:
uptime | sed 's/^.*[[:space:]][[:space:]]*up[[:space:]][[:space:]]*\([[:digit:]]\{1,2\}\):\([[:digit:]]\{1,2\}\).*$/hm/'
Ao contrário do snippet Python, isso extrai a primeira correspondência em vez da última, mas não importa aqui.
A saída de uptime
fica em caracteres de espaço e dígitos ASCII, portanto, você pode simplificar o regex:
uptime | sed 's/^.* up *\([0-9]\{1,2\}\):\([0-9]\{1,2\}\).*$/hm/'
Isso só corresponderá à saída de uptime
se a máquina estiver ativa por menos de 1 dia. Vou deixar coincidindo o número de dias como um exercício. (Dica: escreva duas expressões: sed -e s/AS ABOVE/hm/ -e 's/EXERCISE/dhm/'
)