it-swarm-pt.tech

loop sobre caracteres na cadeia de entrada usando awk

Acredite ou não, não consigo encontrar a resposta para o que eu acho que seria essa pergunta muito básica.

No awk, como posso fazer um loop sobre a string de entrada caractere por caractere? Digamos que eu só queria imprimi-los. Existe uma matriz que eu possa acessar? Ou preciso usar substr?

Basicamente, algo como:

echo "here is a string" | awk '
{ for(i=0; i<[length of input string]; i++) 
    printf [value at index i in array x]; 
}'

Francamente, estou envergonhado.

24
jasonmclose

Você pode converter uma string em uma matriz usando split:

echo "here is a string" | awk '
{ 
  split($0, chars, "")
  for (i=1; i <= length($0); i++) {
    printf("%s\n", chars[i])
  }
}'

Isso imprime os caracteres verticalmente, um por linha.

38
Michael J. Barber

Por padrão em awk a Field Separator (FS) é space ou tabs. Como você mencionou que deseja fazer um loop sobre cada caractere e não o Word, teremos que redefinir o FS para nada. Algo assim -

[jaypal:~/Temp] echo "here is a string" | awk -v FS="" '
{for (i=1;i<=NF;i++) printf "Character "i": " $i"\n"}' 
Character 1: h
Character 2: e
Character 3: r
Character 4: e
Character 5:  
Character 6: i
Character 7: s
Character 8:  
Character 9: a
Character 10:  
Character 11: s
Character 12: t
Character 13: r
Character 14: i
Character 15: n
Character 16: g
19
jaypal singh

Nem todas as implementações do awk suportam as soluções acima. Nesse caso, você pode usar substr:

echo here is a string | awk '{
  for (i=0; ++i <= length($0);) 
    printf "%s\n", substr($0, i, 1)
  }'

P.S. Em algumas implementações awk comprimento sem argumentos, o padrão é $, ou seja, comprimento e comprimento ($ 0) são equivalentes.

8
Dimitre Radoulov

se você tem um bocejo:

awk '$0=gensub(/(.)/,"\\1\n","g")' file

teste:

kent$  echo "I am a String"|awk '$0=gensub(/(.)/,"\\1\n","g")'
I

a
m

a

S
t
r
i
n
g
2
Kent