2012-05-05 63 views
6

Tôi chán và quyết định viết một kịch bản cho một cuộc phiêu lưu dựa trên văn bản của tôi bằng cách sử dụng bash. Về cơ bản, nó được cho là tạo hiệu ứng cho máy đánh chữ trong một số trường hợp nhất định cho kể chuyện đầy kịch tính. Tôi có thể thực hiện việc này theo cách thủ công trong một tệp như vậy:bash: đọc văn bản từ một chuỗi một ký tự cùng một lúc, với khoảng trắng

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" 

Như bạn có thể tưởng tượng, nó thật đáng tẻ nhạt. Thay vào đó, tôi muốn kéo các ký tự từ một chuỗi (hoặc tệp) một ký tự cùng một lúc và áp dụng lệnh ngủ cho mỗi ký tự.

Cho đến nay, tôi có thông tin sau đây, đọc từ tệp. IFS = cho phép các khoảng trống giữ lại, nhưng không cho phép bất kỳ loại khoảng trống nào khác (chẳng hạn như dòng mới).

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

Có cách nào tôi có thể sử dụng để nhận tất cả khoảng trắng? Là một câu hỏi tiền thưởng, bạn có thể cho tôi biết cách áp dụng điều này cho một tập lệnh do người dùng xác định, vì vậy tôi không phải đọc từ một tệp riêng biệt? Vì vậy, ví dụ, cho phép nói rằng tôi có một chuỗi được gọi là "hello", và tôi có thể chỉ cần chuyển nó vào chức năng của tôi để hoạt hình như một máy đánh chữ bất cứ khi nào tôi chạy tập tin của tôi trong thiết bị đầu cuối bash.

Mọi trợ giúp sẽ được đánh giá cao. Cảm ơn!

+0

Làm cách nào để chuyển đổi dòng mới thành dấu cách bằng cách sử dụng 'tr (1)'? – g13n

+0

Nếu tôi hiểu chính xác trang của người đàn ông, tôi có sử dụng tùy chọn tr [: print:] không? – derp

+1

+1 chỉ vì bạn quyết định chống lại sự nhàm chán với bash-scripting :) –

Trả lời

8

Làm thế nào về

#!/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, cảm ơn! Đây chính xác là những gì tôi cần. Tôi vẫn đang học cú pháp cho shell scripting, vì vậy điều này giúp ích rất nhiều. – derp

+0

Không có vấn đề gì về kịch bản shell là thú vị :-) – jedwards

+1

@derp: Không cần các tiện ích 'seq' và' expr' bên ngoài: 'cho ((i = 0; i <$ {# text}; i ++))' –

0

@derp bạn không cần sử dụng tr -s [:blank:] để siết nhiều khoảng trắng thành một chữ cái duy nhất.

HTH.

1

Để trả lời câu hỏi ban đầu, bạn cần phải sử dụng một delimiter trống cũng như:

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

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

Về cơ bản, read sẽ dừng lại ở dòng mới (dấu phân cách mặc định) ngay cả khi nó chưa tiêu thụ đủ nhân vật. Cờ -r cũng cho phép nó để lại dấu gạch chéo ngược một mình.

Giải thích đầy đủ tại đây: http://jayferd.us/posts/2011-01-12-bash-adventures-read-a-single-character-even-if-its-a-newline

Các vấn đề liên quan