以下是本人最近在学习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