SHELL编程语法汇总

本文总结了SHELL编程的基础知识,包括变量与局部变量、特殊变量、参数展开、输入输出、函数、流程控制(IF、WHILE、FOR、UNTIL、CASE)和数组操作。还提供了一个实例,展示如何在指定范围内求素数之和,以及在文件中查找最长字符串的方法。
摘要由CSDN通过智能技术生成

以下是本人最近在学习SHELL编程相关知识过程中的一些笔记,希望能对各位有所帮助,由于水平有限,错误在所难免,欢迎各位指正。
如果这篇笔记对你有帮助不妨加个收藏,如果需要转载的话,请注明出处,感谢。

变量与局部变量

#注意!!等号左右不能有空格
a=12#变量的定义,弱类型,可以用不同角度理解变量的类型可以是整型12,浮点型12,字符串12
a=helloworld
a=`pwd`
a=$<string1>:<string2>#字符串拼接,zsh: a=${<string1>}<string2>

#局部变量
local a=12

特殊变量

#位置变量
$0 #获取当前正在执行的shell脚本的文件名,包括路径。类似C语言main函数参数
$n #获取当前执行shell脚本的第n个参数,n=1...9,如果n>9,则需要将n使用大括号括起来,类似C语言main函数参数
$* #获取当前执行shell脚本的所有参数,将所有命令行参数视为单个字符串,相当于“$1$2$3”,比较少用,与$n类似
$# #得到执行当前脚本的参数个数,不包括脚本名
$@ #获取这个程序所有参数,并保留参数之间的任何空白,相当于“$1” "$2" "$3",这是将参数传给其他程序的最好办法。与$*类似,可以看作一样。
#!/bin/bash
echo "argv[0] = $0"
echo "argv[1] = $1"
echo "argv[2] = $2"
echo "argv[3] = $3"

echo "\$# = $#"
echo "\$* = $*"
echo "\$@ = $@"

#状态变量
$? #返回上一条命令的返回值,判断上一指令是否成功执行,0为成功,非0为不成功
$$ #取当前进程的PID
$! #上一指令的PID

变量参数展开

#find等指令如果搜寻目录未定义会默认指定当前目录为搜寻目录,这时候如果进行删除操作可能会出错,这样就应该用到参数展开
${<parameter>:-word} #如果变量未定义,则表达式的值为word
${<parameter>:=word} #如果变量未定义,则设置变量的值为word,返回表达式的值也是word
${<parameter>:?word} #用于捕捉由于变量未定义而导致的错误并退出程序
${<parameter>:+word} #如果变量已经定义,返回word,也就是真。
#如果没":",则<parameter>为空字符串也算有,所以还是带":"比较好
${!prefix*}
${!prefix@} #prefix开头的变量
${#<parameter>} #输出字符串的长度
${<parameter>:<number>} #从第<number>字符开始截取
${<parameter>:<number>:<length>} #从<number>字符开始截取,取<length>长度
${<parameter>#<pattern>} #从头删除最短匹配<pattern>,zsh无效
${parameter##<pattern>} #从头删除最长匹配<pattern>,比较少用
${parameter%<pattern>} #从尾删除最短匹配<pattern>,zsh无效
${parameter%%<pattern>} #从尾删除最长匹配<pattern>,比较少用
${<parameter>/<pattern>/<string>} #第一个匹配被替换 
${<parameter>//<pattern>/<string>} #全部匹配被替换
${<parameter>/#<pattern>/<string>} #把字符串开头的<pattern>替换为<string>,开头没有则无事发生
${<parameter>/%<pattern>/<string>} #把字符串结尾的<pattern>替换为<string>,结尾没有则无事发生
${<parameter>,,} ${<parameter>^^} #全部转换为小写、大写,zsh无效
${<parameter>,} ${<parameter>^} #首字母转换为小写、大写,zsh无效

输入输出

echo "<string>"
echo -e "Hello World\n" #开启转义 -n 不输出新行
echo "Hello $name, This is world"
echo "\"Hello World\""

read <-options> <variable>
$ read <arg1> <arg2>
$ abc def		#abc存储到<arg1>中,def存储到<arg2>中
-a <array>		#把输入赋值到数组<array>中,从索引号零开始。
-d <delimiter>	#用字符串<delimiter>中的第一个字符指示输入结束,而不是一个换行符
-e 				#使用Readline来处理输入。这使得与命令行相同的方式编辑输入
-n <num>		#读取num个输入字符,而不是整行
-p <prompt>		#使用字符串<prompt>作为输入时显示的提示信息,
-r 				#Raw mode. 不把反斜杠字符解释为转义字符
-s				#Silent mode,输入不会显示,像linux输入密码时一样
-t <time(s)>	#定时输入,超过时间则跳过
-u fd 			#使用文件描述符fd中的输入,而不是标准输入

printf format -string [arguments...]

函数

#!/bin/bash
function _printf_ {
	echo $1
	return
}

_printf_() {
	echo $1
	return
}

function _printf_() {
	echo $1
	return
}
##函数使用方法
_printf_ "Hello World"
##后面的"Hello World"为传入给_printf_函数的参数
##若不传值给函数 echo默认输出空行 而%d默认为0
##函数参数传递从$1开始,$0是程序名

流程控制

  • IF

    #!/bin/bash
    if [[ condition ]]; then
    	#statements
    fi
    
    if [[ condition ]]; then
    	#statements
    	else
    		#statements
    fi 
    
    if [[ condition ]]; then
    	#statements
    elif [[ condition ]]; then
    	#statements
    elif [[ condition ]]; then
    	#statements
    	else
    	#statements
    fi
    ##注意!!condition两侧空格不能省略
    #条件中的关系运算符不是> < ...,详细参考 man test(只能判断字符串,整型,文件三种数据类型)
    
  • WHILE

    #!/bin/bash
    while [[ condition ]]; do
    	#statements
    done
    
  • FOR

    for i in words; do
    	#statements
    done
    
    for i in `seq 0 100`; do
    	#statements
    done
    
    for (( i = 0; i < 10; i++ )); do
    	#statements
    done
    #seq 0 100 输出从0到100间隔默认为1的所有数,类似matlab
    
  • UNTIL

    #!/bin/bash
    until [[ condition ]]; do
    	#statements
    done
    
  • CASE

    #!/bin/bash
    case word in
    	pattern1 )
    		#statements
    		;;
    	pattern2 )
    		#statements
    		;;
    		...
    esac
    #要取用变量word,记得加$
    

数组操作

#数组声明
declare -a a
##name[subscript]=value
##name=(value1 value2 ...)

#数组操作
#输出数组所有内容
${arry[*]}
${arry[@]}
#确定数组元素个数
${#arry[@]}
#找到数组的下标
${!arry[@]}

#数组追加
<arry>+=(a b c)
#数组排序,利用管道
sort
#删除数组与元素
unset <arry>

例子

给定起始数字start_num与终止数字end_num输出该范围内所有素数的和,使用线性筛方法求解

#!/bin/bash
declare -a prime
function usage() {
    printf "Usage : %s start_num end_num\n" $0 
}

function init() {
    S=$1
    E=$2
    for (( i=$S; i<=$E; i++ ));do
        prime[$i]=0
    done
}

if [[ $# -ne 2  ]]; then
    usage
    exit
fi

start_num=$1
end_num=$2

if [[ ${start_num} -lt 0 ]];then
    start_num=0
fi
if [[ ${start_num} -gt ${end_num} ]];then
    usage
    exit
fi

init 0 ${end_num}


for (( i=2; i<=${end_num}; i++ ));do
    if [[ ${prime[$i]} -eq 0 ]];then
        prime[0]=$[ ${prime[0]} + 1 ]
        prime[${prime[0]}]=$i
        if [[ $i -ge ${start_num} ]];then
            sum=$[ ${sum} + $i ]
        fi
    fi
    for (( j=1; j<=${prime[0]}; j++  ));do
        if [[ $[ ${i} * ${prime[$j]} ] -gt ${end_num} ]];then
            break
        fi
        prime[$[ ${i} * ${prime[$j]} ]]=1
        if [[ $[ ${i} % ${prime[$j]} ] -eq 0 ]];then
            break
        fi
    done
done
echo ${sum}

求一个文件中的最长字符串

#!/bin/bash
max_len=0
max_string=''
if [[ $# -lt 1 ]];then
    printf "Usage: %s file [...]\n" $0
fi

#for (( i=1; i<=$#; i++ ));do
#    echo $i
#done

for i in `cat $1 | tr -s -c "a-zA-Z" " "`;do
    len=${#i}
    if [[ $len -gt ${max_len} ]];then
        max_len=$len
        max_string=$i
    fi
done

echo $max_string $max_len
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值