杨辉三角显示扩展

1 普通的杨辉三角打印

#!/bin/bash

if [ -z "$1" ];then
        read -p "Pls input a number: " MAX
else
        MAX=$1
fi

for ((i=1;i<=$MAX;i++))
        do
                for ((j=1;j<=$i;j++))
                        do
                                f=$((i-1))
                                g=$((j-1))
                                if [ $j -eq 1 ] || [ $j -eq $i ];then
                                        declare SUM_${i}_${j}=1
                                else
                                        declare M=$[SUM_${f}_${g}]
                                        declare N=$[SUM_${f}_${j}]
                                        declare SUM_${i}_${j}=$((M+N))
                                fi
                                echo -ne "$[SUM_${i}_${j}] "
                        done
                                echo
        done

直接传参和read读入参数,并未对参数的类型判断

$(( )) 和$[ ] 运算是一样的效果

以行列变量下标定义变量时注意定义的意义的有效性,本身带有${ }的变量嵌套,外面需要$[ ] 且要用declare声明,否者出错

[ ]与[ ]之间的关系用 || 和 && 判断

现对输出所有结果居中处理

未处理输出样式如下:

[root@localhost script]# bash  Yanghuisanjiao2.sh  10
1 
1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1 
1 5 10 10 5 1 
1 6 15 20 15 6 1 
1 7 21 35 35 21 7 1 
1 8 28 56 70 56 28 8 1 
1 9 36 84 126 126 84 36 9 1 

 

 

 

方法一:

#!/bin/bash

if [ -z $1 ];then
        echo -ne "\033[32mPls input a num: \033[0m"
        read MAX
else
        MAX=$1

fi

i=0
while [ $i -le $MAX ]
        
        do
                for ((m=$MAX;m>=$i;m--))
                do
                        [ $m -gt $i ] &&  printf  "  "
                done
                j=1
                while [ $j -le $i  ]
                
                
                        do
                                f=$[i-1]
                                g=$[j-1]
                                if [ $j -eq 1 ] || [ $j -eq $i ];then
                                        declare SUM_${i}_${j}=1
                                else
                                        declare A=$[SUM_${f}_${g}]
                                        declare B=$[SUM_${f}_${j}]
                                        declare SUM_${i}_${j}=$(expr $A + $B)
                                fi
                                printf "%-4s" "$[SUM_${i}_${j}]  "
                                let j++
                        done
                        echo
                        let i++
        done

输出结果: 此类处理方法在行数较少的时候,尚可,行数较多,计算结果的数字位数组件无规律增长,则无法较美观的显示,结果如下

[root@localhost script]# bash G2.sh 9
                  
                1   
              1   1   
            1   2   1   
          1   3   3   1   
        1   4   6   4   1   
      1   5   10  10  5   1   
    1   6   15  20  15  6   1   
  1   7   21  35  35  21  7   1   
1   8   28  56  70  56  28  8   1   
[root@localhost script]# bash G2.sh 20
                                        
                                      1   
                                    1   1   
                                  1   2   1   
                                1   3   3   1   
                              1   4   6   4   1   
                            1   5   10  10  5   1   
                          1   6   15  20  15  6   1   
                        1   7   21  35  35  21  7   1   
                      1   8   28  56  70  56  28  8   1   
                    1   9   36  84  126  126  84  36  9   1   
                  1   10  45  120  210  252  210  120  45  10  1   
                1   11  55  165  330  462  462  330  165  55  11  1   
              1   12  66  220  495  792  924  792  495  220  66  12  1   
            1   13  78  286  715  1287  1716  1716  1287  715  286  78  13  1   
          1   14  91  364  1001  2002  3003  3432  3003  2002  1001  364  91  14  1   
        1   15  105  455  1365  3003  5005  6435  6435  5005  3003  1365  455  105  15  1   
      1   16  120  560  1820  4368  8008  11440  12870  11440  8008  4368  1820  560  120  16  1   
    1   17  136  680  2380  6188  12376  19448  24310  24310  19448  12376  6188  2380  680  136  17  1   
  1   18  153  816  3060  8568  18564  31824  43758  48620  43758  31824  18564  8568  3060  816  153  18  1   
1   19  171  969  3876  11628  27132  50388  75582  92378  92378  75582  50388  27132  11628  3876  969  171  19  1  

 

方法二:

1,对其他定长字符的格式输出的了解和扩展

#!/bin/bash

triangle(){
       for((i=1;i<=$1;i++));do
               RES=$(($i*2-1))
               for((j=1;j<=$i;j++));do
                       echo -n ' '
               done

               for((j=$2;j>$RES;j--));do
                       echo -n '*'
               done
               echo ''
       done
}

triangle $1 $2

输出结果

[root@localhost script]# bash daosanjiao.sh 10 20
 *******************
  *****************
   ***************
    *************
     ***********
      *********
       *******
        *****
         ***
          *

结论,此类方法和上面的类似,无法融合到处理不定长字符的居中显示,且echo 和 printf 目前也没有居中的格式

tput与terminfo

tput 命令将通过 terminfo 数据库对您的终端会话进行初始化和操作。通过使用 tput,您可以更改几项终端功能,如移动或更改光标、更改文本属性,以及清除终端屏幕的特定区域。

UNIX 系统上的 terminfo 数据库用于定义终端和打印机的属性及功能,包括各设备(例如,终端和打印机)的行数和列数以及要发送至该设备的文本的属性。
UNIX 中的几个常用程序都依赖 terminfo 数据库提供这些属性以及许多其他内容,其中包括 vi 和 emacs 编辑器以及 curses 和 man 程序。

tput常用法

tput默认通过$TERM的值来指示终端类型,但我们也可以通过 -T $Type 来指定终端类型。不过一般来说都没有这个必要。

下面的用法中都上略对-T参数的说。

  • tput capname [parameters]: 这是tput最常用的方式,具体用法见下一章.
  • tput init: 初始化终端,在使用tput前一般会先执行该命令
  • tput reset: 重置终端属性为默认值
  • tput clear: 清屏
  • tput -S: 从stdin中读取指令,可以支持一次性设置多个指令,但必须保证一个指令一行.

tput的使用

tput一般用于作三件事情: 设置终端属性,获取终端属性以及判断终端是否支持某项能力.

但请记住,tput并不支持设置颜色!

另外,在使用tput的输出值时,请一定先保证tput的返回值为0!

设置终端属性

tput主要是通过输出控制码字符串来实现一些特殊终端效果的.

  • bel: 警铃
  • blink: 进入闪烁模式
  • bold: 进入粗体模式
  • civis: 隐藏鼠标
  • cnorm: 取消隐藏鼠标
  • clear: 清屏
  • cup rc: 将光标移动到第r,c列
  • el: 清除到行尾
  • ell: 清除到行首
  • smso: 进入凸出模式
  • rmso: 退出凸出模式
  • smul: 进入下划线模式
  • rmul: 退出下划线模式
  • sc: 保存光标当前位置
  • rc: 回复光标最后保存的位置
  • rev: 进入反转模式
  • sgr0: 回复正常显示
  • setf n/setbn: 设置前景色/背景色.$n为在terminfo数据库中的颜色数值,一般对应关系为:

    数值颜色
    0 黑色
    1 蓝色
    2 绿色
    3 青色
    4 红色
    5 洋红色
    6 黄色
    7 白色
  • setaf n/setabn: 使用ANSI的转义字符来设置前景色/背景色.

下面是一个例子

#!/bin/bash

BOLD=$(tput bold)
REV=$(tput rev)
NORMAL=$(tput sgr0)
CURSOR_OFF=$(tput civis)
CURSOR_ON=$(tput cnorm)

tput init

tput clear
echo $CURSOR_OFF
tput cup 2 15
echo -e "${BOLD}粗体效果{NORMAL}\n"
echo  "${REV}反转效果${NORMAL}"
echo $CURSOR_ON

获取终端属性

tput会输出一个数字,表示该属性的值.

  • cols: 获取终端一行有多少列字符
  • lines: 获取终端一列有多少行字符
  • it: 终端的TAB相当于几个空格

下面是一个例子

echo "The terminal is $(tput cols) x $(tput lines)"

The terminal is  x

判断终端是否存在某项能力

tput会通过返回值来表示是否具有这项能力(0表示true,1表示false).

  • chts: 光标是否不可见
  • hs: 终端是否具有状态行

下面是一个例子:

if tput hs;then
    echo "your terminal has a status lne"
else
    echo "your terminal has NO status line"
fi

your terminal has NO status line

 

一、控制颜色

代码:

 

复制代码 代码如下:

 


#!/bin/sh
function colour ()
{
  case $1 in
    black_green)
       echo -e '\033[40;32m'

    black_yellow)
       echo -e '\033[40;33m'

    black_white)
       echo -e '\033[40;37m'

    black_cyan)
       echo -e '\033[40;36m'

    black_red)
       echo -e '\033[40;31m'

    colour_default)
       echo -e '\033[0m'

   esac
}

 

二、定位
代码:

 

复制代码 代码如下:

 


#!/bin/sh
function xy ()
{
  _R=$1
  _C=$2
  _TEXT=$3
  tput  cup $_R $_C
  echo -n $_TEXT
}

 

三、居中显示
代码:

 

复制代码 代码如下:


#!/bin/sh
function center ()
{
 _STR=$1
 _ROW=$2
 LEN=`echo $_STR | wc -c`
 COLS=`tput cols`
 HOLD_COL=`expr $COLS - $LEN`
 NEW_COL=`expr $HOLD_COL / 2`
 tput cup $_ROW $NEW_COL
 echo -n $_STR
}

1.文本属性

tput Color Capabilities:

tput setab [0-7] – Set a background color using ANSI escape
tput setb [0-7] – Set a background color
tput setaf [0-7] – Set a foreground color using ANSI escape
tput setf [0-7] – Set a foreground color

Color Code for tput:

0 – Black
1 – Red
2 – Green
3 – Yellow
4 – Blue
5 – Magenta
6 – Cyan
7 – White

tput Text Mode Capabilities:

tput bold – Set bold mode
tput dim – turn on half-bright mode
tput smul – begin underline mode
tput rmul – exit underline mode
tput rev – Turn on reverse mode
tput smso – Enter standout mode (bold on rxvt)
tput rmso – Exit standout mode
tput sgr0 – Turn off all attributes

例子:使输出的字符串有颜色,底色,加粗

#!/bin/bash

printf $(tput setaf 2; tput bold)'color show\n\n'$(tput sgr0)

for((i=0; i<=7; i++)); do
	echo $(tput setaf $i)"show me the money"$(tput sgr0)
done

printf '\n'$(tput setaf 2; tput setab 0; tput bold)'background color show'$(tput sgr0)'\n\n'

for((i=0,j=7; i<=7; i++,j--)); do
	echo $(tput setaf $i; tput setab $j; tput bold)"show me the money"$(tput sgr0)
done

exit 0



输出格式控制函数:

#!/bin/bash

# $1 str       print string
# $2 color     0-7 设置颜色
# $3 bgcolor   0-7 设置背景颜色
# $4 bold      0-1 设置粗体
# $5 underline 0-1 设置下划线

function format_output(){
	str=$1
	color=$2
	bgcolor=$3
	bold=$4
	underline=$5
	normal=$(tput sgr0)

	case "$color" in
		0|1|2|3|4|5|6|7)
			setcolor=$(tput setaf $color;) ;;
		*)
			setcolor="" ;;
	esac

	case "$bgcolor" in
		0|1|2|3|4|5|6|7)
			setbgcolor=$(tput setab $bgcolor;) ;;
		*)
			setbgcolor="" ;;
	esac

	if [ "$bold" = "1" ]; then
		setbold=$(tput bold;)
	else
		setbold=""
	fi

	if [ "$underline" = "1" ]; then
		setunderline=$(tput smul;)
	else
		setunderline=""
	fi

	printf "$setcolor$setbgcolor$setbold$setunderline$str$normal\n"
}

format_output "Yesterday Once More" 2 5 1 1

exit 0


2.光标属性

#!/bin/bash

tput clear # 清屏

tput sc # 保存当前光标位置

tput cup 10 13 # 将光标移动到 row col

tput civis # 光标不可见

tput cnorm # 光标可见

tput rc # 显示输出

exit 0

例子:

#!/bin/bash
# clear the screen
tput clear
# Move cursor to screen location X,Y (top left is 0,0)
tput cup 3 15
# Set a foreground colour using ANSI escape
tput setaf 3
echo "XYX Corp LTD."
tput sgr0
tput cup 5 17
# Set reverse video mode
tput rev
echo "M A I N - M E N U"
tput sgr0
tput cup 7 15
echo "1. User Management"
tput cup 8 15
echo "2. Service Management"
tput cup 9 15
echo "3. Process Management"
tput cup 10 15
echo "4. Backup"
# Set bold mode
tput bold
tput cup 12 15
read -p "Enter your choice [1-4] " choice
tput clear
tput sgr0
tput rc

exit 0

 

 

 

以上tput资料为网络搜索

 

最后杨辉三角处理结果

 

#!/bin/bash
function center(){
_STR=$1
_ROW=$2
LEN=`echo $_STR|wc -L`
COLS=`tput cols`
HOLD_COL=`expr $COLS - $LEN`
NEW_COL=`expr $HOLD_COL / 2`
[ ${NEW_COL} -lt 0 ] && echo -e "\033[31mWarning: Beyond the screen edge !\033[0m\n" && exit 5
tput cup $_ROW $NEW_COL
echo -ne "$_STR\n\n"
}
tput clear
if [ -z $1 ];then
        echo -ne "\033[32mPls input a num: \033[0m"
        read MAX
else
        MAX=$1
fi

i=1
while [ $i -le $MAX ]
        
        do
                j=1
                LINE=""
                while [ $j -le $i  ]
                        do
                                f=$[i-1]
                                g=$[j-1]
                                if [ $j -eq 1 ] || [ $j -eq $i ];then
                                        declare SUM_${i}_${j}=1
                                else
                                        declare A=$[SUM_${f}_${g}]
                                        declare B=$[SUM_${f}_${j}]
                                        declare SUM_${i}_${j}=$(expr $A + $B)
                                fi
                                NUM=`echo -n " $[SUM_${i}_${j}] "`
                                LINE=${LINE}${NUM}
                                let j++
                        done
                        center "`echo $LINE`" $[i-1]
                        let i++
        done

 

结束。

 

 

 

 

    

 

posted @ 2017-08-26 13:36  Dothraki  阅读(252)  评论(0)    收藏  举报