Existem várias perguntas relacionadas, parece que eles não usam awk
para resolver o problema.
- Extraindo números de ponto flutuante positivos/negativos de uma string
- Como extrair os números de um nome de arquivo
echo "blah foo123bar234blah" | egrep -o '([0-9]+)'
retorna
123
234
Mas
echo "blah foo123bar234blah" |
awk '{ match($0,/([0-9]+)/,m); print m[0], m[1],m[2]}'
retorna 123 123
e
echo "blah foo123bar234blah" |
awk '{ match($0,/([0-9]+).+([0-9]+)/,m); print m[0], m[1],m[2]}'
retorna 123bar234 123 4
No manual , na seção: match(string, regexp [, array]) , o exemplo é:
echo foooobazbarrrrr |
gawk '{ match($0, /(fo+).+(bar*)/, arr); print arr[1], arr[2]}'
Que retorna foooo barrrrr
.
Então, como posso extrair vários números de uma string usando awk (equivalente a grep -o
)?
Com GNU awk para multi-char RS e RT:
Com qualquer awk (e mantendo o regexp original em vez de negá-lo, pois isso só é fácil com uma expressão de colchetes simples e não uma abordagem geral robusta):
ou:
A
match()
função executa uma única correspondência de sua expressão regular. Para encontrar cada execução de dígitos usando correspondência de expressão regular commatch()
em GNUawk
, você precisa fazer um loop.Estamos interessados apenas
a[0]
aqui, pois não usamos parênteses em nossa expressão regular. Não usamos parênteses em nossa expressão porque não precisamos deles. Possivelmente precisaríamos de parênteses se quiséssemos combinar um número conhecido de inteiros com uma única expressão (por exemplo([0-9]+)[^0-9]+([0-9]+)
, , etc.), mas neste exercício não sabemos realmente quantos inteiros podem existir.Ou, com padrão
awk
,Isso corresponde a execuções de dígitos consecutivos na string em
str
. Para cada correspondência, a string correspondente é impressa e a partestr
que não é mais interessante é removida usandosubstr()
.Teste:
Você pode usar a
gsub()
função deawk
e transformar todas as ocorrências de "substrings que não consistem em dígitos" em espaços simples e, em seguida, usar asplit()
função para dividir a string resultante no espaço em branco. Isso se comporta como divisão de campo naFS
variável padrão e descarta "campos vazios" à esquerda e à direita:Então, para o seu exemplo:
Para extrair
0-9
dígitos em inglês, usando GNU awk para o FPAT:ou com qualquer awk:
ou especificamente usando a função match() (nenhum benefício BTW, pois sabemos que filtramos apenas dígitos em
[^0-9]+
, então todo o resto são apenas dígitos, mas sim, para evitar a impressão de campos vazios, é útil, mas não melhor do$i+0==$i
que acima):Se você realmente deseja apenas extrair números (números naturais e zero no exemplo a seguir!), você pode definir qualquer outra coisa como separadores de campo:
(adicionada alguma formatação para retornar entradas separadas por espaço para uma linha por registro)
E também outra opção usando GNU
awk
parapatsplit()
:por que torná-lo tão complexo com todo esse FPAT e patsplit e while(match()) -
apenas isto basta: