2012-05-05 8 views
6

Estoy aburrido, y decidí escribir un script para una aventura mía basada en texto usando bash. Básicamente, se supone que debe animar una máquina de escribir en ciertos casos para contar historias dramáticas. Puedo hacerlo manualmente en un archivo como el siguiente:bash: leer texto de una cadena de un carácter a la vez, con espacios en blanco

sleep 0.1 
echo -n "h" 
sleep 0.1 
echo -n "e" 
sleep 0.1 
echo -n "l" 
sleep 0.1 
echo -n "l" 
sleep 0.1 
echo -n "o" 

Como se puede imaginar, es tremendamente tedioso. En cambio, quiero extraer caracteres de una cadena (o archivo) un carácter a la vez, y aplicar el comando dormir a cada personaje.

Hasta ahora, tengo lo siguiente, que se lee de un archivo. IFS = permite retener los espacios, pero no cualquier otro tipo de espacio en blanco (como nueva línea).

IFS= 
while read -n1 achar 
do 
    echo $achar 
done < aFile 

¿Hay alguna manera de que pueda usar esto para obtener todos los espacios en blanco? Como una pregunta de bonificación, ¿puede decirme cómo aplicar esto a un script definido por el usuario, para que no tenga que leer desde un archivo separado? Entonces, por ejemplo, digamos que tengo una cadena llamada "hola", y simplemente puedo pasarla a mi función para animarla como una máquina de escribir cada vez que ejecuto mi archivo en la terminal de bash.

Cualquier ayuda sería apreciada. ¡Gracias!

+0

¿Qué hay de convertir las nuevas líneas de espacios utilizando 'tr (1)'? – g13n

+0

Si entiendo correctamente la página man, ¿uso la opción tr [: print:]? – derp

+1

+1 solo porque decidiste luchar contra el aburrimiento con bash-scripting :) –

Respuesta

8

¿Qué tal

#!/bin/bash 

function typewriter 
{ 
    text="$1" 
    delay="$2" 

    for i in $(seq 0 $(expr length "${text}")) ; do 
     echo -n "${text:$i:1}" 
     sleep ${delay} 
    done 
} 


typewriter "Typewriters are cool." .1 
echo # <-- Just for a newline 
+0

Wow, gracias! Esto es exactamente lo que necesitaba. Todavía estoy aprendiendo la sintaxis para el script de shell, así que esto ayuda mucho. – derp

+0

No hay problema al crear scripts en shell es divertido :-) – jedwards

+1

@derp: no es necesario utilizar las utilidades 'seq' y' expr' externas: 'for ((i = 0; i <$ {# text}; i ++))' –

0

@derp no necesita usar tr -s [:blank:] para exprimir múltiples espacios en blanco a uno solo.

HTH.

1

Para responder a la pregunta original, es necesario utilizar un delimitador de vacíos y:

#!/bin/bash 
getc() { 
    IFS= read -r -n1 -d '' "[email protected]" 
} 

typewriter() { 
    while getc ch; do 
    sleep 0.1; echo "$ch" 
    done 
} 

Básicamente, read se detendrá en los saltos de línea (el delimitador predeterminado), incluso si no ha consumido suficientes caracteres todavía. La bandera -r también le dice que deje las barras invertidas solo.

explicación completa aquí: http://jayferd.us/posts/2011-01-12-bash-adventures-read-a-single-character-even-if-its-a-newline

Cuestiones relacionadas