2012-05-05 10 views
6

Sono annoiato e ho deciso di scrivere uno script per una mia avventura basata su testo utilizzando bash. Fondamentalmente, si suppone che animi una macchina da scrivere in certi casi per uno storytelling drammatico. Posso farlo manualmente in un file in questo modo:bash: lettura del testo da una stringa un carattere alla volta, con spazi

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" 

Come potete immaginare, è terribilmente noioso. Invece, voglio tirare caratteri da una stringa (o file) un carattere alla volta e applicare il comando di sonno a ciascun carattere.

Finora, ho il seguente, che legge da un file. IFS = consente agli spazi di conservare, ma non qualsiasi altro tipo di spazio bianco (come newline).

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

C'è un modo per utilizzarlo per ottenere tutti gli spazi bianchi? Come domanda bonus, puoi dirmi come applicarlo a uno script definito dall'utente, quindi non devo leggere da un file separato? Quindi, per esempio, diciamo che ho una stringa chiamata "ciao", e posso semplicemente passarla alla mia funzione per animare come macchina da scrivere ogni volta che eseguo il mio file nel terminale bash.

Qualsiasi aiuto sarebbe apprezzato. Grazie!

+0

Come sulla conversione di nuove righe in spazi, utilizzando 'tr (1)'? – g13n

+0

Se comprendo correttamente la pagina man, posso usare l'opzione tr [: print:]? – derp

+1

+1 solo perché hai deciso di combattere la noia con bash-scripting :) –

risposta

8

Come su

#!/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, grazie! Questo è esattamente ciò di cui avevo bisogno. Sto ancora imparando la sintassi per lo scripting di shell, quindi questo aiuta molto. – derp

+0

Nessun problema con lo scripting della shell è divertente :-) – jedwards

+1

@derp: Non sono necessarie le utilità esterne 'seq' e' expr': 'for ((i = 0; i <$ {# text}; i ++))' –

0

@derp no è necessario utilizzare tr -s [:blank:] per spremere più spazi vuoti in uno solo.

HTH.

1

per rispondere alla domanda originale, è necessario utilizzare un separatore vuoto così:

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

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

In sostanza, read si fermerà a nuove righe (il delimitatore di default), anche se non ha ancora consumato abbastanza caratteri. Il flag -r dice anche di lasciare le backslash da solo.

completa spiegazione qui: http://jayferd.us/posts/2011-01-12-bash-adventures-read-a-single-character-even-if-its-a-newline

Problemi correlati