だから私は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にもモジュールがあります!確認してみてください。これは例です。