Bash - 文字列を美しくスクロール

Bash - 文字列を美しくスクロール

だから私はbashを使ってコンソールから美しい水平スクロールテキストを作成しようとしています。私は何をすべきかわかりません。例は次のとおりです。

Original string: Hi! How are you doing on this fine evening?

1st loop:
Hi! H
2nd:
i! Ho
3rd:
! How
4th:
 How 

など。どうすればいいですか?最後に印刷されたループを削除して、滑らかなスクロール文字列になることをお勧めします。どんな助けでも大変感謝します!ありがとうございます! (質問も自由に聞いてみてください。説明が少し不便ですね:P)

答え1

これは少しハッキング的ですが、これがあなたが説明する効果だと思います。出力では、各行は前の項目を上書きするため、<marquee> 前のタグと同様の内容が端末に生成されます。

Hello There!
ello There! He
o There! Hello
There! Hello
ere! Hello The
e! Hello There
Hello There!
ello There! He
lo There! Hell
There! Hello
here! Hello Th
re! Hello Ther
! Hello There!
Hello There! H
llo There! Hel
o There! Hello
There! Hello T
here! Hello Th
e! Hello There
Hello There!
#!/bin/bash

function slice_loop () { ## grab a slice of a string, and if you go past the end loop back around
    local str="$1"
    local start=$2
    local how_many=$3
    local len=${#str};

    local result="";

    for ((i=0; i < how_many; i++))
    do
        local index=$(((start+i) % len)) ## Grab the index of the needed char (wrapping around if need be)
        local char="${str:index:1}" ## Select the character at that index
        local result="$result$char" ## Append to result
    done

    echo -n $result
}

msg="Hello There! ";
begin=0

while :
do
    slice=$(slice_loop "$msg" $begin 14);
    echo -ne "\r";
    echo -n $slice;
    echo -ne "              \r";
    sleep 0.08;
    ((begin=begin+1));
done

ファイルに保存して実行すると、文字列の"Hello There!"スクロールが通過するのがわかります。少しタイトですが、調整してよりきれいにすることができます。

答え2

他の人が言ったように、またはおよびechoキャリッジprintfリターンを使用する必要があります\r

したがって、必要なのはループごとに5文字だけを印刷することです。次のスクリプトを使用してその動作を達成できます。

#!/bin/bash

null=$'\0'
text="Hi! How are you doing on this fine evening? ${null}"

#while :; do
count=0
for (( i = 0; i < "${#text}"; i++ )); do
   printf "\r%s" "${text:$i:5}"
   sleep 0.3
done
#done
echo

この行を使用すると、printf "\r%s" "${text:$i:5}"ループごとに5文字を印刷します。ここでは、$i現在のインデックスで、5印刷する文字列の長さです。
たとえば、text次のように変数を印刷する場合:

printf "%s" "${text:0:5}"
#Output
Hi! H
printf "%s" "${text:1:5}"
#Output
i! Ho
#and so on

すべての文字列を印刷し、各ループの左側にあるすべての文字を削除するには、次のスクリプトを使用できます。

#!/bin/bash

null=$'\0'
text="Hi! How are you doing on this fine evening? ${null}"

#while :; do
count=0
for (( i = 0; i < "${#text}"; i++ )); do
   printf "\r%s" "${text:$i}"
   sleep 0.3
done
#done
echo

上記のコードは次のように印刷されます。

最初のループでは:

Hi! How are you doing on this fine evening?

2番目のループでは:

i! How are you doing on this fine evening?

3番目のループでは:

! How are you doing on this fine evening?

など。

メモ:$nullこの変数は、文字列の最後に最後の文字が印刷されるのを防ぐために使用する必要があります(この場合)?。無限ループが必要な場合と#while :; do行のコメントを外す必要があります#done

答え3

echo -e "\r"あなたの友人です:\ rはキャリッジリターンのシンボルです(あなたがタイプライターの前に座っていると想像してください!)。これはカーソルを現在の行の先頭に戻します。

だから、

#!/bin/bash
echo -n "foobar"
#     ^---------- don't print a newline at the end of the line!
sleep 1
echo -e -n "\rbaz"
#        ^------- don't print a newline at the end of the line!
#     ^---------- evaluate escape sequences like \r
echo -e -n "\rB"

を印刷してfoobarしばらく待ってfooから上書きし、baz小文字を大文字で直接上書きするとB結果はですBazbar

これが必要なスクロールバーでなければなりません!

実際にアニメーションを適用するには複雑すぎます。端末のほぼすべての場所で変更できるライブラリを使用するプログラムを作成しようとしています。 (n)cursesはそのようなライブラリの1つです。 Pythonにもモジュールがあります!確認してみてください。これは例です

関連情報