pslaboが試したことの記録

はてなダイヤリーからはてなブログに引っ越してきました

この日記は現在実行中の減量記録を含む個人的なメモとして始めましたが、最近はコンピュータやガジェット、ハック、セキュリティネタのほうがメインになっております。

はてなダイヤリー時代はカテゴリ分けが適当だったのですが、これはそのうち直します。


echo や cat を文字、単語、行単位でゆっくり表示する関数を bash で書いてみた

echo や cat のような処理を普通に行うのは味気ないので、ゆっくり表示する関数を bash で書いてみました。

f:id:pslabo:20160209224639g:plain

対話的な処理をスクリプトで書く場合に、目的に応じてメッセージ表示のしかたを変えたい場合に使えるかも??
また echo については -n や -e の引数も指定できるように実装してみました。

表示のタイミングは waittime のハッシュ配列で変えられます。
また flag で interactive を 0 にすればゆっくり表示する処理は無効にできます。

#!/bin/bash

declare -A waittime
declare -A flag


waittime=(
        ["word"]=0.15
        ["line"]=0.18
        ["char"]=0.015
        ["char_long"]=0.005
        ["no_newline_wait"]=0.5
        ["newline_wait"]=1.0
)

flag=(
        ["verbose"]=1
        ["interactive"]=1
)

do_main() {

slowtype << EOF
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.

EOF

slowwordtype << EOF
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.

EOF

slowcat << EOF
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.

EOF

}


######################################################################
# 1文字づつ表示する echo
# slowecho [-en] "string"
######################################################################
slowecho() {
        if [ ${flag["verbose"]} -eq 0 ]; then
                return
        fi

        if [ ${flag["interactive"]} -eq 0 ]; then
                echo "$@"
                return
        fi

        local echo_newline="\n"
        local echo_param="-n"
        local OPTIND_BACKUP=${OPTIND}

        OPTIND=1
        while getopts ne OPT
        do
                case $OPT in
                        n)
                        echo_newline=""
                        ;;

                        e)
                        echo_param="-en"
                        ;;
                esac
        done
        OPTIND=${OPTIND_BACKUP}

        local string=$( echo "$@" )
        local string_ptr=0
        local linechars=${#string}
        local char_wait=${waittime["char"]}

        if [ $linechars -gt 20 ]; then
                char_wait=${waittime["char_long"]}
        fi

        for (( string_ptr=0 ; string_ptr <= ${linechars} ; string_ptr++ )); do
                echo ${echo_param} "${string:$string_ptr:1}"
                sleep ${char_wait}
        done

        if [ "${echo_newline}" == "" ]; then
                sleep ${waittime["no_newline_wait"]}
        else
                echo -en "${echo_newline}"
        fi
}

######################################################################
# 1単語づつ表示する echo
# slowwordecho [-en] "string"
######################################################################
slowwordecho() {
        if [ ${flag["verbose"]} -eq 0 ]; then
                return
        fi

        if [ ${flag["interactive"]} -eq 0 ]; then
                echo "$@"
                return
        fi

        local echo_newline="\n"
        local echo_param="-n"
        local OPTIND_BACKUP=${OPTIND}

        OPTIND=1
        while getopts ne OPT
        do
                case $OPT in
                        n)
                        echo_newline=""
                        ;;

                        e)
                        echo_param="-en"
                        ;;
                esac
        done
        OPTIND=${OPTIND_BACKUP}

        local string=$( echo "$@" )
        local string_ptr=0
        local linechars=${#string}

        local wordbuffer=""
        local prev_char=""
        for (( string_ptr=0 ; string_ptr <= ${linechars} ; string_ptr++ )); do
                case "${string:$string_ptr:1}" in
                        ';' | ':' | ',' | '.' | '\t' | ' ' | ' ' )
                        prev_char="blankspace"
                        ;;

                        *)
                        if [ "${prev_char}" == "blankspace" ]; then
                                echo ${echo_param} "${wordbuffer}"
                                sleep ${waittime["word"]}
                                wordbuffer=""
                                prev_char="char"
                        fi
                        ;;
                esac
                wordbuffer="${wordbuffer}${string:$string_ptr:1}"
        done
        echo ${echo_param} "${wordbuffer}"
        sleep ${waittime["word"]}

        if [ "${echo_newline}" == "" ]; then
                sleep ${waittime["no_newline_wait"]}
        else
                echo -en "${echo_newline}"
        fi
}

######################################################################
# 1行づつ表示する cat
# some_command | slowcat
######################################################################
slowcat() {
        if [ ${flag["verbose"]} -eq 0 ]; then
                return
        fi

        if [ ${flag["interactive"]} -eq 0 ]; then
                cat
                return
        fi

        # 1行づつ表示
        local line
        local IFS_BACKUP=${IFS}
        IFS=$'\n'
        while read line ; do
                echo "${line}"
                sleep ${waittime["line"]}
        done
        IFS=${IFS_BACKUP}
}

######################################################################
# 1文字づつ表示する cat
# some_command | slowtype
######################################################################
slowtype() {
        if [ ${flag["verbose"]} -eq 0 ]; then
                return
        fi

        if [ ${flag["interactive"]} -eq 0 ]; then
                cat
                return
        fi

        local line
        local IFS_BACKUP=${IFS}
        IFS=$'\n'
        while read line ; do
                slowecho "${line}"
        done
        IFS=${IFS_BACKUP}
}

######################################################################
# 1単語づつ表示する cat
# some_command | slowtype
######################################################################
slowwordtype() {
        if [ ${flag["verbose"]} -eq 0 ]; then
                return
        fi

        if [ ${flag["interactive"]} -eq 0 ]; then
                cat
                return
        fi

        local line
        local IFS_BACKUP=${IFS}
        IFS=$'\n'
        while read line ; do
                slowwordecho "${line}"
        done
        IFS=${IFS_BACKUP}
}

do_main "$@"