print to the end of terminal

白昼怎懂夜的黑 提交于 2019-12-10 23:09:46

问题


Like this picture of apt-get, how can I print something at the end of the line, just like the speed on the screen. Although I can use escape like \e[C to make it move several columns to the right and print, but the speed varies and the string length varies. Can anyone tell me how to do this? I am currently programming using bash. Thanks.


回答1:


Often you will find the width of the console window in the environment variable COLUMNS, but this is not completely reliable. A more reliable solution is to use the tput utility (part of ncurses, but can be used standalone) with the argument cols:

$ echo $COLUMNS
148
$ tput cols
148

A simple way to split text is to use the Posix-standard printf utility to first print the text to be aligned on the right margin padded to the column width, then output a carriage return (\r) to return the cursor to the beginning of the line, and then print the text to be aligned on the left margin. Finally a newline will move to the next line. Or, in code:

# Call it like this:
# print_both_sides "This goes on the left" "and this goes on the right."
print_both_sides() {
  printf "\r%*s\r%s\n" $(tput cols) "$2" "$1";
}

The printf format uses the standard feature of * replacements for field width and precision format modifiers; the * means that the corresponding number should be taken from an argument. In this case, I use $(tput cols) -- i.e. the width of the console window -- as the first argument for the format code %*s, which has the effect of right-padding the next string argument ("$2") in a field whose width is precisely the width of the console.

I added an additional carriage return to the beginning of the output in case the cursor is currently not at the left margin.




回答2:


In a terminal, there is more than one way to obtain the actual screen-width:

  • if the terminal/connection can successfully negotiate the screen size, that (usually) results in a correct value shown in stty -a (the columns value usually on the first line of the report).
  • the command-line tput utility consults this information, overriding any constant value for the number of columns from the terminal database, and can print it, e.g, tput cols.
  • the environment variables LINES and COLUMNS usually override that in full-screen applications (including those using curses: see use_env).
  • sometimes the information is just wrong (see the xterm FAQ Why is my screensize not set?). For terminals supporting the VT100-style cursor-position report (also in ECMA-48, 8.3.14 CPR - ACTIVE POSITION REPORT), you can use resize to update the stty setting and optionally update LINES and COLUMNS.

When printing using escape sequences, there are a few different ways to use this information about the screen-width, which are widely supported. The command-line tput utility also can retrieve these from the terminal description (which may lack specific features):

  • absolute cursor positioning, allows you to move the cursor to a specific row and column on the screen: tput cup $row $column
  • horizontal cursor positioning, allows you to move the cursor to a specific column on the current row: tput hpa $column
  • relative cursor positioning, allows you to move the cursor left or right (or up or down), a given number of cells, e.g., tput cuf $value to move forward (to the right) by the given number of cells. Regarding the question, using a parameter like this is usually faster than repeating single movements as done with tputcuf1.

The capabilities cup, hpa, cuf correspond generally to names in ECMA-48 and are described in the terminfo(5) manual page.

To print text at the right-side of the screen, you would do this:

  • obtain the number of columns in the screen,
  • determine the number of columns which your text will use,
  • compute the starting column: right-margin minus the number of columns in the text
  • move the cursor to the starting column
  • print the text, e.g., using echo or printf. The latter has more flexibility.

If you use the command-line printf utility, you may keep in mind that handling multibyte characters such as UTF-8 is not well-supported when you want to know the width of a given string, so portability may be a concern.

Further reading:

  • printf field width doesn't support multibyte characters?
  • UTF-8 Width Display Issue of Chinese Characters


来源:https://stackoverflow.com/questions/35052500/print-to-the-end-of-terminal

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!