Как распечатать ту же строку, переопределяя предыдущую строку?
иногда я вижу некоторые команды в терминале, которые печатают результаты в stdout, но в той же строке. Например, wget печатает стрелку, как показано ниже:
0[=> ]100%
0[ => ]100%
0[ => ]100%
0[ => ]100%
0[ =>]100%
но он распечатан в той же строке, поэтому похоже, что стрелка движется. Как я могу достичь того же в своих программах, используя bash или sh? Нужно ли использовать другие инструменты?
обновление:
Я знаю, что я упомянул wget, который поставляется по умолчанию в linux, gnu на основе unices ... Есть общие подход, который работает и на BSDs? (как OSX) -> OK, если я использую bash вместо sh, то он работает:)
3 ответов
используйте специальный символ \r
. Он возвращается к началу строки, не переходя к следующей.
for i in {1..10} ; do
echo -n '['
for ((j=0; j<i; j++)) ; do echo -n ' '; done
echo -n '=>'
for ((j=i; j<10; j++)) ; do echo -n ' '; done
echo -n "] $i"0% $'\r'
sleep 1
done
можно использовать \r
для этого:
например, это будет продолжать обновлять текущее время в той же строке:
while true; do echo -ne "$(date)\r"; done
вы также можете использовать ANSI/VT100 terminal escape sequences
для достижения этой цели.
вот краткий пример. Конечно, вы можете объединить printf
заявления на один.
#!/bin/bash
MAX=60
ARR=( $(eval echo {1..${MAX}}) )
for i in ${ARR[*]} ; do
# delete from the current position to the start of the line
printf "\e[2K"
# print '[' and place '=>' at the $i'th column
printf "[\e[%uC=>" ${i}
# place trailing ']' at the ($MAX+1-$i)'th column
printf "\e[%uC]" $((${MAX}+1-${i}))
# print trailing '100%' and move the cursor one row up
printf " 100%% \e[1A\n"
sleep 0.1
done
printf "\n"
С escape-последовательностями у вас больше всего контроля над экраном терминала.
вы можете найти обзор возможных последовательностей в [1].