因此,我尝试使用 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
这个有点hacky,但我相信这就是你所描述的效果。在输出中,每一行都会覆盖前一个条目,以便它生成类似于旧<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
orprintf
和回车符\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?
在第二个循环中:
i! How are you doing on this fine evening?
在第三个循环中:
! 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 就是这样一个库——甚至 Python 也有一个模块!我建议检查一下。这是一个例子。