User Tools

Site Tools


haas:spring2017:unix:projects:usf0

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
haas:spring2017:unix:projects:usf0 [2017/03/12 19:41] – [Output Formatting with printf(1)] wedgehaas:spring2017:unix:projects:usf0 [2017/03/13 15:05] (current) – [Specifications] wedge
Line 171: Line 171:
 You'll notice that everything lines up and is positioned similarly: You'll notice that everything lines up and is positioned similarly:
  
-  * each column exists within 8 characters of on-screen real estate, with one addition space padding the left and the right margins of the column.+  * each column exists within 8 characters of on-screen real estate, with one additional space padding the left and the right margins of the column.
   * The values are right justified with each column, with all bases but decimal being exactly the same length (prepending leading zeroes if necessary)   * The values are right justified with each column, with all bases but decimal being exactly the same length (prepending leading zeroes if necessary)
   * The dashes and vertical bars set up an ASCII art-like table pattern that helps make the data more readable.   * The dashes and vertical bars set up an ASCII art-like table pattern that helps make the data more readable.
Line 192: Line 192:
 Fear not! The **printf(1)** tool comes to your rescue! Fear not! The **printf(1)** tool comes to your rescue!
  
-Like **echo**, **printf** displays information to the screen (STDOUT). In fact, various programming languages that want more powerful output formatting implement some form of printf into their vast libraries.+Like **echo**, **printf** displays information to the screen (STDOUT). In fact, various programming languages (like C and C++) that want more powerful output formatting implement some form of printf into their vast libraries.
  
 Be sure to check the manual page for options and functionality; following will be a few usage examples. Be sure to check the manual page for options and functionality; following will be a few usage examples.
Line 219: Line 219:
  
 Be sure to check the manual page for additional escape characters. Be sure to check the manual page for additional escape characters.
 +
 +===Format specifiers===
 +Now, we know from using **echo** we can utilize shell variable and command expansions to make our output more dynamic.
 +
 +But, **printf** adds additional formatting capability that **echo** lacks. If the string we are displaying contains **%** symbols, substitutions can be made and behaviors invoked; functionality that **echo** lacks.
 +
 +Some common format specifiers:
 +
 +  * **%d** - substitute integer (whole number) value
 +  * **%s** - substitute string value
 +  * **%c** - substitute single character
 +  * **%f** - substitute floating point value
 +  * **%o** - substitute integer (whole number) value and represent in octal
 +  * **%x** - substitute integer (whole number) value and represent in hexadecimal
 +
 +First up, a simple example:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ printf "%d\n" 175
 +175
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +Then, adding to it:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ printf "The number: %d\n" 175
 +The number: 175
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +That 175 can also be in a variable:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ value=175
 +lab46:~/src/unix/usf0$ printf "The number: %d\n" ${value}
 +The number: 175
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +You may want to wrap the variable in double quotes, to avoid cases where it might be NULL and otherwise generate an error (I generally quote all my variables to be on the safe side).
 +
 +How about substitutions with strings?
 +
 +<cli>
 +lab46:~/src/unix/usf0$ printf "Your username is: %s\n" "${USER}"
 +Your username is: username
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +And in general just crafting super effective format strings:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ value=175
 +lab46:~/src/unix/usf0$ printf "%d %s %X\n" "${value}" "is hexadecimal" "${value}"
 +175 is hexadecimal AF
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +Please take note, where there are multiple format specifiers, substitution is in order of specification... **%d** was the first, **%s** was the second, and **%X** was the third in that particular string, so the first value following the string is grabbed by the **%d**, the next the **%s**, and the third the **%X**. Ordering matters (which should make sense).
 +
 +===Output formatting===
 +So now, getting to where **printf** really excels, formatting your output.
 +
 +It turns out, that between the **%** and whatever format option you specify, you can provide a numeric value which will impact how that number appears on the screen, commonly in the form of preallocated space to display within.
 +
 +For instance:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ printf "Testing: >>%4d<<\n" 47
 +Testing: >>  47<<
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +See what happened there? 47 was displayed, but WITHIN a block of 4 characters. Also of note, by default output is **right justified**.
 +
 +To **left** justify, simply make it negative:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ printf "Testing: >>%-4d<<\n" 47
 +Testing: >>47  <<
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +We can also pad with zeros, that is represented by decimal values:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ printf "Testing: >>%.3d<<\n" 49
 +Testing: >>049<<
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +This can be combined with justify and space allocation:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ printf "Testing: >>%-6.3d<<\n" 49
 +Testing: >>049   <<
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +Other neat tricks? We can variable-ize the padding by using a **<nowiki>*</nowiki>**:
 +
 +<cli>
 +lab46:~/src/unix/usf0$ spacing=4
 +lab46:~/src/unix/usf0$ printf "Testing: >>%*d<<\n" "${spacing}" 49
 +Testing: >>  49<<
 +lab46:~/src/unix/usf0$ 
 +</cli>
 +
 +The **printf** tool is super-powerful and useful for output, so mastering its use adds an impressive capability to your repertoire.
 +
 +Play with **printf** and experiment... you'll find it can accomplish some impressive output feats that previously may have been more complicated.
 =====Submission===== =====Submission=====
 By successfully performing this project, you should have a fully functioning script by the name of **usf0.sh**, which is all you need to submit for project completion. By successfully performing this project, you should have a fully functioning script by the name of **usf0.sh**, which is all you need to submit for project completion.
Line 237: Line 349:
  
 <code> <code>
-78:upf1:final tally of results (78/78) +78:usf0:final tally of results (78/78) 
-*:upf1:upf1steps submitted via submit tool [2/2+*:usf0:usf0.sh submitted with submit tool [3/3
-*:upf1:upf1steps covers steps from copy until submit [4/4] +*:usf0:usf0.sh has a shabang invoking bash [3/3
-*:upf1:upf1steps squelches any STDERR output [4/4] +*:usf0:usf0.sh runs without error [6/6
-*:upf1:upf1steps only displays required STDOUT output [4/4] +*:usf0:usf0.sh with no arguments displays default table [6/6
-*:upf1:task0.cli produces correct result [2/2+*:usf0:usf0.sh is commented explaining implementation [6/6
-*:upf1:task0.cli uses specified input_value [1/1+*:usf0:table heading and separators conform to project specifications [6/6
-*:upf1:task0.cli uses specified input_unit [1/1+*:usf0:values are calculated, not literally displayed [6/6
-*:upf1:task0.cli solution in specified output_unit [2/2+*:usf0:binary column is correct and formatted to specifications [6/6
-*:upf1:task0.cli solution using specified precision [1/1+*:usf0:octal column is correct and formatted to specifications [6/6
-*:upf1:task0.cli solution using specified delimiter [1/1+*:usf0:decimal column is correct and formatted to specifications [6/6
-*:upf1:task1.cli produces correct result [2/2+*:usf0:hexadecimal column is correct and formatted to specifications [6/6
-*:upf1:task1.cli uses specified input_value [1/1] +*:usf0:starting value is properly checked for and verified [6/6
-*:upf1:task1.cli uses specified input_unit [1/1] +*:usf0:ending value is properly checked for and verified [6/6
-*:upf1:task1.cli solution in specified output_unit [2/2] +*:usf0:signed option is properly checked for and verified [6/6]
-*:upf1:task1.cli solution using specified precision [1/1] +
-*:upf1:task1.cli solution using specified delimiter [1/1] +
-*:upf1:task2.cli produces correct result [2/2+
-*:upf1:task2.cli uses specified input_value [1/1] +
-*:upf1:task2.cli uses specified input_unit [1/1] +
-*:upf1:task2.cli solution in specified output_unit [2/2] +
-*:upf1:task2.cli solution using specified precision [1/1] +
-*:upf1:task2.cli solution using specified delimiter [1/1] +
-*:upf1:task3.cli produces correct result [2/2+
-*:upf1:task3.cli uses specified input_value [1/1] +
-*:upf1:task3.cli uses specified input_unit [1/1] +
-*:upf1:task3.cli solution in specified output_unit [2/2] +
-*:upf1:task3.cli solution using specified precision [1/1] +
-*:upf1:task3.cli solution using specified delimiter [1/1] +
-*:upf1:task4.cli produces correct result [2/2+
-*:upf1:task4.cli uses specified input_value [1/1+
-*:upf1:task4.cli uses specified input_unit [1/1+
-*:upf1:task4.cli solution in specified output_unit [2/2] +
-*:upf1:task4.cli solution using specified precision [1/1] +
-*:upf1:task4.cli solution using specified delimiter [1/1] +
-*:upf1:task5.cli produces correct result [2/2] +
-*:upf1:task5.cli uses specified input_value [1/1] +
-*:upf1:task5.cli uses specified input_unit [1/1] +
-*:upf1:task5.cli solution in specified output_unit [2/2] +
-*:upf1:task5.cli solution using specified precision [1/1] +
-*:upf1:task5.cli solution using specified delimiter [1/1] +
-*:upf1:task6.cli produces correct result [2/2] +
-*:upf1:task6.cli uses specified input_value [1/1] +
-*:upf1:task6.cli uses specified input_unit [1/1] +
-*:upf1:task6.cli solution in specified output_unit [2/2] +
-*:upf1:task6.cli solution using specified precision [1/1] +
-*:upf1:task6.cli solution using specified delimiter [1/1] +
-*:upf1:task7.cli produces correct result [2/2] +
-*:upf1:task7.cli uses specified input_value [1/1] +
-*:upf1:task7.cli uses specified input_unit [1/1] +
-*:upf1:task7.cli solution in specified output_unit [2/2] +
-*:upf1:task7.cli solution using specified precision [1/1] +
-*:upf1:task7.cli solution using specified delimiter [1/1]+
 </code> </code>
haas/spring2017/unix/projects/usf0.1489347664.txt.gz · Last modified: 2017/03/12 19:41 by wedge