snipplets:print_horizontal_line

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
snipplets:print_horizontal_line [2011/07/09 04:58]
ormaaj spelling
snipplets:print_horizontal_line [2018/05/09 23:37] (current)
pdeyoreo added missing newline between sections "The iterative way" and "The simple printf way"
Line 15: Line 15:
 Not a miracle, just to be complete here. Not a miracle, just to be complete here.
  
-<​code>​ +<​code ​bash
-# of course you can use echo(1), too +printf ​'%s\n' --------------------
-printf ​-- '​--------------------\n'+
 </​code>​ </​code>​
  
Line 23: Line 22:
 This one simply loops 20 times, always draws a dash, finally a newline This one simply loops 20 times, always draws a dash, finally a newline
  
-<​code>​+<​code ​bash>
 for ((x = 0; x < 20; x++)); do for ((x = 0; x < 20; x++)); do
-  printf -- '​-'​+  printf ​%s -
 done done
-printf '​\n'​+echo
 </​code>​ </​code>​
 +
 ===== The simple printf way ===== ===== The simple printf way =====
 This one uses the ''​printf''​ command to print an **empty** field with a **minimum field width** of 20 characters. The text is padded with spaces, since there is no text, you get 20 spaces. The spaces are then converted to ''​-''​ by the ''​tr''​ command. This one uses the ''​printf''​ command to print an **empty** field with a **minimum field width** of 20 characters. The text is padded with spaces, since there is no text, you get 20 spaces. The spaces are then converted to ''​-''​ by the ''​tr''​ command.
  
-<​code>​ +<​code ​bash
-printf '​%20s\n'​ | tr ' ​' '-'+printf '​%20s\n'​ | tr ' ' -
 </​code>​ </​code>​
  
-whitout an external command, using a bash specific ​expansion:​ +whitout an external command, using the (non-POSIX) substitution ​expansion ​and ''​-v''​ option
-<​code>​ +<​code ​bash
-printf -v res '%20s' +printf -v res %20s 
-printf ​"%s\n" ​"​${res//​ /-}"+printf ​'%s\n' ​"​${res//​ /-}"
 </​code>​ </​code>​
  
 ===== A line across the entire width of the terminal ===== ===== A line across the entire width of the terminal =====
-This one is a variant of the one above. It uses ''​tput cols''​ to find the width of the terminal and set that number as the minimum field witdh.+This is a variant of the above that uses ''​tput cols''​ to find the width of the terminal and set that number as the minimum field witdh.
  
-<​code>​ +<​code ​bash
-printf ​"%$(tput cols)s\n"|tr ' ' '='+printf ​'%*s\n' "​${COLUMNS:​-$(tput cols)}" '' ​| tr ' ' ​-
 </​code>​ </​code>​
 +
 ===== The more advanced printf way ===== ===== The more advanced printf way =====
-This one is a bit tricky. The format for the ''​printf''​ command is ''​%.0s'',​ which specified a field with the **maximum** length of **zero**. After this field, ''​printf''​ is told to print a dash. You might remember that it's the nature of ''​printf''​ to repeat, if the number of format ​specifications is less than the number of given arguments. With brace expansion ''​{1..20}'',​ 20 arguments are given (you could easily write ''​1 2 3 4 ... 20'',​ of course!). Following happens: The **zero-length field** plus the dash is repeated 20 times. A zero length field is, naturally, invisible. What you see is the dash, repeated 20 times.+This one is a bit tricky. The format for the ''​printf''​ command is ''​%.0s'',​ which specified a field with the **maximum** length of **zero**. After this field, ''​printf''​ is told to print a dash. You might remember that it's the nature of ''​printf''​ to repeat, if the number of conversion ​specifications is less than the number of given arguments. With brace expansion ''​{1..20}'',​ 20 arguments are given (you could easily write ''​1 2 3 4 ... 20'',​ of course!). Following happens: The **zero-length field** plus the dash is repeated 20 times. A zero length field is, naturally, invisible. What you see is the dash, repeated 20 times.
  
-<​code>​ +<​code ​bash
-# Note: you might see that as %.s, which is a (less documented) shorthand for %.0s +# Note: you might see that as ''​%.s''​, which is a (less documented) shorthand for ''​%.0s''​ 
-printf '​%.0s-'​ {1..20} +printf '​%.0s-'​ {1..20}; echo
-printf '​\n'​+
 </​code>​ </​code>​
-if the 20 is variable, you can use eval (take care that using eval is potentially dangerous if you evaluate external data): + 
-<​code>​ +If the 20 is variable, you can use [[commands:​builtin:​eval | eval]] to insert the expansion ​(take care that using ''​eval'' ​is potentially dangerous if you evaluate external data): 
-eval printf ​'%.0s-' {1..$(tput cols)}+ 
 +<​code ​bash
 +eval printf %.0s- '{1..'"​${COLUMNS:​-$(tput cols)}"\}; echo 
 +</​code>​ 
 + 
 +Or restrict the length to 1 and prefix the arguments with the desired character. 
 + 
 +<code bash> 
 +eval printf %.1s '​-{1..'"​${COLUMNS:​-$(tput cols)}"​\};​ echo 
 +</​code>​ 
 + 
 +You can also do it the crazy ormaaj way™ following basically the same principle as this [[commands:​builtin:​eval#​expansion_side-effects | string reverse example]]. It completely depends on Bash due to its brace expansion evaluation order and array parameter parsing details. As above, the eval only inserts the COLUMNS expansion into the expression and isn't involved in the rest, other than to put the ''​_''​ value into the environment of the ''​_[0]''​ expansion. This works well since we're not creating one set of arguments and then editing or deleting them to create another as in the previous examples. 
 + 
 +<code bash> 
 +_=- command eval printf %s '"​${_[0]"​{0..'"​${COLUMNS:​-$(tput cols)}"'​}"​}"';​ echo
 </​code>​ </​code>​
  
 ===== The parameter expansion way ===== ===== The parameter expansion way =====
  
-Preparing enough dashes in advance, we can then use a (bash specific) ​expansion:+Preparing enough dashes in advance, we can then use a non-POSIX subscript ​expansion:
  
-<​code>​+<​code ​bash>
 hr=---------------------------------------------------------------\ hr=---------------------------------------------------------------\
 ---------------------------------------------------------------- ----------------------------------------------------------------
-echo ${hr:​0:​$(tput cols)} +printf '​%s\n'​ "${hr:0:${COLUMNS:-$(tput cols)}}" 
-</​code> ​+</​code>​ 
 + 
 +A more flexible approach, and also using modal terminal line-drawing characters instead of hyphens: 
 + 
 +<code bash> 
 +hr() { 
 +  local start=$'​\e(0'​ end=$'​\e(B'​ line='​qqqqqqqqqqqqqqqq'​ 
 +  local cols=${COLUMNS:​-$(tput cols)} 
 +  while ((${#line} < cols)); do line+="​$line";​ done 
 +  printf '​%s%s%s\n'​ "​$start"​ "​${line:​0:​cols}"​ "​$end"​ 
 +
 +</​code>​
  
 ===== Related articles ===== ===== Related articles =====
   * [[commands:​builtin:​printf]]   * [[commands:​builtin:​printf]]
  • snipplets/print_horizontal_line.1310187514.txt
  • Last modified: 2011/07/09 04:58
  • by ormaaj