Bar graph with bash

I am currently using:

#!/bin/bash while read line do ((histogram[${#line}]++)) done < "${1:-/dev/stdin}" for length in "${!histogram[@]}"; do printf "%-1s %s\n" "${length}" "${histogram[$length]}" done 

to generate a histogram output. But if there are no length lines, the output automatically lowers them. Is there any way to prevent the function from skipping these lines? Any ideas?

+7
bash
source share
2 answers

Do you want you to print zero for each carrier length to the maximum length? If yes:

 $ cat test.sh #!/bin/bash while read line do ((histogram[${#line}]++)) done < "${1:-/dev/stdin}" max=0 for length in "${!histogram[@]}" do if [ $length -gt $max ] then max=$length fi done for length in $(seq 0 $max) do printf "%-1s %s\n" "${length}" "${histogram[$length]-0}" done 

Execution Example:

 $ printf 'x\nfoo\n' | ./test.sh 0 0 1 1 2 0 3 1 
+1
source share

Bash uses sparse arrays by default. For example. there could be holes in the array. You can avoid them by initializing (filling) the array in advance. Of course, you need to evaluate the maximum index. e.g. add to top

 histogram=( $(printf "%0.s0\n" {1..10}) ) # generate 10 zeroes 

after you run how

 printf "%s\n" 1 123 123 123456 | bash the_script 

You'll get:

 0 0 1 1 2 0 3 2 4 0 5 0 6 1 7 0 8 0 9 0 

or , if you do not want to initialize in advance, you need to check the existence of this member and execute a loop for each

 while read line do ((histogram[${#line}]++)) done < "${1:-/dev/stdin}" max=$(printf "%s\n" "${!histogram[@]}" | sort -nr | head -1) for ((length=0; length<=max; length++ )) { val=${histogram[$length]:-0} printf "%-1s %s\n" "${length}" "$val" } 

eg. for the above printf "%s\n" 1 123 123 123456 | bash the_script printf "%s\n" 1 123 123 123456 | bash the_script

 0 0 1 1 2 0 3 2 4 0 5 0 6 1 
+1
source share

All Articles