问题
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(thecolumnsvalue 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
LINESandCOLUMNSusually 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
sttysetting and optionally updateLINESandCOLUMNS.
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 $valueto 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 withtputcuf1.
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
echoorprintf. 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