Eu tenho uma variável bash contendo várias linhas de texto, que inclui endereços IP, e preciso remover 'tudo' antes da última ocorrência de endereço IP na mesma linha.
Este:
43.12.40.53 [email protected]
archery-666.foobar.com 66.77.11.44 data test@example
55.32.39.153 [email protected]
5.113.30.37 dummy
89-109-22-006.static.example.com.br 89.109.22.6 [email protected]
68.28.15.55 68.28.15.55 another
deve ser transformado em:
43.12.40.53 [email protected]
66.77.11.44 data test@example
55.32.39.153 [email protected]
5.113.30.37 dummy
89.109.22.6 [email protected]
68.28.15.55 another
Lendo este post Como posso excluir tudo até um padrão e tudo depois de outro padrão de uma linha? Eu tentei:
var=$(sed 's/^.*\(([0-9]{1,3}[\.]){3}[0-9]{1,3}\).*$/\1/' <<< "$var")
mas não funciona.
Algumas questões:
você está misturando BRE e ERE (por exemplo
\(
versus(
para o agrupamento)seu
.*
no final precisa estar dentro do grupo de captura se você quiser que o resultado inclua tudo depois do IPo
^.*
no início consumirá avidamente o máximo de caracteres possível - incluindo todos, exceto um dos principais dígitos de IPAlém disso,
.
não precisa ser escapado por dentro[]
- embora isso não quebre nada.Não tenho certeza da maneira CERTA de lidar com (3) em
sed
que (ao contrário deperl
dizer) não possui um modificador não ganancioso. Adicionar uma âncora de limite de palavra\b
parece funcionar, mas parece frágilEntão ou (BRE)
ou (ERE)
Você escapou corretamente o primeiro parênteses, mas não o segundo e não o
{}
que também precisa escapar. Além disso, você está combinando tudo com o final da linha (.*$
) que não é necessário. Usando seu regex, isso faria o que você deseja:Mas isso ainda é mais complicado do que o necessário. Por exemplo, você não precisa
[\.]
, um simples\.
é suficiente. E você pode usar o-E
sinalizador para habilitar expressões regulares estendidas e simplificar sua sintaxe para:No entanto, como steeldriver aponta , sua liderança
.*
pode consumir mais do que você espera, então seria mais seguro fazer tudo em perl: