Shell脚本

一,规则:

1,等号左右两边不能有空格,调用变量需要在变量名前面加$

2,变量赋值常用的符号

  1)双引号:允许引用其他的变量值

    test=1

    echo "这是变量test:$test"

  2)单引号:禁止引用其他变量

    test=2

    echo "这不现实变量:$test"

  3)反撇:将命令执行的结果赋值给变量

    aaa=`echo "这是命令"`

  4)read -p:接收用户输入内容赋值给变量使用

    read -p "请输入内容" test

    echo $test

  5)字符串可以不加引号,应用变量的时候也可以不加引号

    echo 这是一个字符串

3,变量的运算符(运算符左右之间需要加空格,不然就是字符串了,而且每个运算前面都需要加。 expr   )

  +:加 

  -:减

  *:

  /:除       expr   $a \ $b * $a

4,流程控制语句(内容里面需要两头空格)

  if [ command ];then

     符合该条件执行的语句

  elif [ command ];then

     符合该条件执行的语句

  else

     符合该条件执行的语句

  fi

  4.1,  运算符     描述                                        示例

    文件比较运算符:

    -e filename 如果 filename 存在,则为真.      [ -e /var/log/syslog ]

    -d filename 如果 filename 为目录,则为真. [ -d /tmp/mydir ]

    -f filename 如果 filename 为常规文件,则为真. [ -f /usr/bin/grep ]

    -L filename 如果 filename 为符号链接,则为真 [ -L /usr/bin/grep ]

    -r filename 如果 filename 可读,则为真         [ -r /var/log/syslog ]

    -w filename 如果 filename 可写,则为真.    [ -w /var/mytmp.txt ]

    -x filename 如果 filename 可执行,则为真. [ -L /usr/bin/grep ]

    filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ]

    filename1 -ot filename2 如果 filename1 比 filename2 旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]

    字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法):

    -z string 如果 string 长度为零,则为真 [ -z "$myvar" ]

    -n string 如果 string 长度非零,则为真 [ -n "$myvar" ]

    string1 = string2 如果 string1 与 string2 相同,则为真 [ "$myvar" = "one two three" ]

    string1 != string2 如果 string1 与 string2 不同,则为真 [ "$myvar" != "one two three" ]

    算术比较运算符

    num1 -eq num2 等于 [ 3 -eq $mynum ]

    num1 -ne num2 不等于 [ 3 -ne $mynum ]

    num1 -lt num2 小于 [ 3 -lt $mynum ]

    num1 -le num2 小于或等于 [ 3 -le $mynum ]

    num1 -gt num2 大于 [ 3 -gt $mynum ]

    num1 -ge num2 大于或等于 [ 3 -ge $mynum ]

 

4.2,测试命令

test命令用于检查某个条件是否成立,它可以进行数值、字符和文件3个方面的测试,其测试符和相应的功能分别如下。

1)数值测试:

  -eq 等于则为真。

  -ne 不等于则为真。

  -gt 大于则为真。

  -ge 大于等于则为真。

  -lt 小于则为真。

  -le 小于等于则为真。

2)字串测试:

  = 等于则为真。

  != 不相等则为真。

  -z字串 字串长度伪则为真。

  -n字串 字串长度不伪则为真。

3)文件测试:

  -e文件名 如果文件存在则为真。

  -r文件名 如果文件存在且可读则为真。

  -w文件名 如果文件存在且可写则为真。

  -x文件名 如果文件存在且可执行则为真。

  -s文件名 如果文件存在且至少有一个字符则为真。

  -d文件名 如果文件存在且为目录则为真。

  -f文件名 如果文件存在且为普通文件则为真。

  -c文件名 如果文件存在且为字符型特殊文件则为真。

  -b文件名 如果文件存在且为块特殊文件则为真

  举例:1)盘 /mnt是否是目录,是目录显示yes不是为空

    test -d /mnt/ && echo "yes"

4.3 if [[ ]]和[ ]区别 || &&

1)[]和test:两者是一样的,在命令行里test expr和[ expr ]的效果相同。

  test的三个基本作用是判断文件、判断字符串、判断整数。支持使用 ”与或非“ 将表达式连接起来,test中可用的比较运算符只有==和!=

  在[]中想进行比较实用><需要进行转义, 如果比较"ab"和"bc":[ ab \< bc ],结果为真,也就是返回状态为0.

2)[[ ]]这是一个内置命令,支持通配符,逻辑组合等

  字符串的模式匹配(使用=~操作符时甚至支持shell的正则表达 式)

  逻辑组合可以不使用test的-a,-o而使用&& ||

  举例:字符串比较时可以把右边的作为一个模式(这是右边的字符串不加双引号的情况下。如果右边的字符串加了双引号,则认为是一个文本字符串。),而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。

总结:

  用[[ ... ]]测试结构比用[ ... ]更能防止脚本里的许多逻辑错误。比如说,&&,||,<和>操作符能在一个[[]]测试里通过,但在[]结构会发生错误。

  [[]]结构比Bash版本的[]更通用。在[[和]]之间的所有的字符都不会被文件扩展或是标记分割,但是会有参数引用和命令替换。

  [[ ... ]]进行算术扩展,而[ ... ]不做

  [[ ... && ... && ...  ]] [ ... -a ... -a ...] 不一样,[[ ]] 是逻辑短路操作,而 [ ] 不会进行逻辑短路

 5,其他命令

1)time 程序执行用的时间

(2)`date +%Y%m%d` 返回当天的时间戳(可以加符号):20150309

(3)last_date=`date -d last-day +%Y%m%d`  昨天的时间20150308

(4),sleep 30 睡眠30秒(支持s,m,h

 

二,应用

1,字符串切割

  方法一: 利用shell 变量 的字符串替换   
    ${parameter//pattern/string} 用string来替换parameter变量中所有匹配的pattern

    string="hello,shell,split,test" 
    array=(${string//,/ })     #返回的列表

  方法二: 设置分隔符,通过 IFS 变量

       Shell 的环境变量分为 set, env 两种,其中 set 变量可以通过 export 工具导入到 env 变量中。其中,set 是显示设置shell变量,仅在本 shell 中有效;env 是显示设置用户环境变量 ,仅在当前会话中有效。换句话说,set 变量里包含了 env 变量,但 set 变量不一定都是 env 变量。这两种变量不同之处在于变量的作用域不同。显然,env 变量的作用域要大些,它可以在 subshell 中使用。

       而 IFS 是一种 set 变量,当 shell 处理"命令替换"和"参数替换"时,shell 根据 IFS 的值,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。

    示例: 

      string="hello,shell,split,test" 
      #对IFS变量 进行替换处理
      OLD_IFS="$IFS"
      IFS=","
      array=($string)
      IFS="$OLD_IFS"         # 返回列表

  方法三: 利用tr 指令实现字符替换  (!只能针对单个分隔符)

    由于只是对单个字符进行的替换,则可以用  echo args |   tr "oldSpilt" "newSpilt"  的方式实现。

    语法

      tr(选项)(参数)

    选项

      -c或——complerment:取代所有不属于第一字符集的字符;

      -d或——delete:删除所有属于第一字符集的字符;

      -s或--squeeze-repeats:把连续重复的字符以单独一个字符表示;

      -t或--truncate-set1:先删除第一字符集较第二字符集多出的字符。

    参数

      字符集1:指定要转换或删除的原字符集。当执行转换操作时,必须使用参数“字符集2”指定转换的目标字符集。但执行删除操作时,不需要参数“字符集2”;

      字符集2:指定要转换成的目标字符集。

      string="hello,shell,split,test" 
      array=(`echo $string | tr ',' ' '` ) 

2,数组

定义:使用declare -a 命令定义数组(数组的索引是从0开始计数的),接下来就可以通过[]操作符为不同索引位置的元素赋值。

  declare -a names

  names[0]=tom

  names[1]=jack

定义并赋值

  #定义的同时直接赋值

  declare -a names=(tom jack)

  #增加元素

  names[2]=sue

  # 直接定义list=(one two three)

取值:指定下标,使用[]操作符从数组中对应元素,然后使用$取值,格式:${数组名[索引]}

获得数组中所有值:${数组名[@]}${数组名[*]}

长度:利用”@”或“*”字符,将数组扩展成列表,然后使用”#”来获取数组元素的个数。

  echo "数组days的元素个数为:${#days[@]}"

  echo "数组names的元素个数为:${#names[*]}"

 

遍历

1)${数组名[@]}、${数组名[@]}均可以获得所有元素(不管是元素列表,还是一整个字符串),使用for循环遍历即可

  for day in ${days[*]}  #或${days[@]}

  do

          echo $day

  done

2)带数组下标的遍历,当需要使用到数组的下标时,可以使用${!数组名[@]}

  for i in ${!days[@]}

  do

          echo ${days[$i]}

  done

3)while循环:根据元素的个数遍历,但对于稀疏数组,可能会丢失数据

  names=()   #数组names是一个稀疏数组

  names[1]=tom

  names[2]=jack

  i=0

  while [ $i -lt ${#names[*]} ]

  do

          echo ${names[$i]}

          let i++

  done

删除:删除一个数组或数组中元素用unset命令。

  unset 数组名[索引]      #删除索引下的元素

  unset 数组名         #删除整个数组

  连接:用()将多个数组连接在一起,()中各个数组用空格隔开。

  days=(one two three four)

  names=(tom jack)

  days=(${days[@]} ${names[@]})

 

三,高级

.正则表达式

1.正则表达式的作用和组成

1)正则表达式的作用

  按照规则对文本数据进行过滤处理

  帮助用户快速查找文本内容

2)正则表达式的组成

  普通字符串

  大写字母A-Z

  小写字母a-z

  符号

  元字符

2.正则表达式的常见选项和应用

1)正则表达式常见的选项

  -n:显示行号

  -0:显示匹配内容

  -i:不区分大小写

  -vn:取反

2)正则表达式常见的元字符

  ^:起始内容

  $:结束内容

  .:匹配任意单个字符

  []:匹配括号中的内容

  [-]:匹配括号里边内容的范围

  {n}:匹配范围的次数

  {n1-n2}:匹配开始和结束内容

  [^]:匹配括号之外的任意字符

  :转义字符

3.grep的应用

1)过滤关键字中包换the的并且显示行号

  grep -n "the" test.txt

2)查找开头是the的行

  grep -n "^the" test.txt

3)匹配任意单个字符开头是w中间任意结束为d的关键字

  grep -n "w..d" test.txt

4)匹配括号里边的内容(任意一个)

  grep -n "sh[io]rt" test.txt

5)只显示匹配内容

  grep -o "wood" test.txt

4.扩展正则表达式

1)扩展正则表达式常见的选项

  +:重复一个或者一个以上的前一个字符

  ?:显示当前字母前的一个字符

  |:或者,多出多个字符

  ():查找组字符串

  ()+:辨别多个重复的组

 

二,sed的作用和工作流程

1,sed的作用

  sed是一个文本文件解释转换工具,用于读取,修改,显示配置文件数据

2,sed处理数据的流程

  读取:从文件,输入,管道命令读取数据,临时储存读取的数据

  执行:根据sed命令在模式操作空间中进行无交互修改数据

  显示:将文本文件的修改结果显示给用户

3,sed命令常见选项操作符

3.1,sed命令常见的选项

  -n:显示处理后的结果

  -h:显示帮助

  -e:指定使用脚本或者命令处理文本数据

  -f:指定脚本处理输入的文本数据

  -i:直接编辑文本文件

3.2,sed常见的操作符

  a:添加内容

  d:删除内容

  p:打印内容

  s:替换内容

  y:字符转换

  c:将指定行替换成指定内容

  i:向匹配行插入指定内容

4.sed的应用

4.1.显示1到5行的数据

  sed -n '1,5p' test.txt

4.2.显示奇数行

  sed -n -e '1p;3p;5p' test.txt

4.3.删除第一行数据

  sed '1d' test.txt

4.4.将大写Linux替换成小写

  sed -i 's/Liunx/liunx' test.txt

4.5.对ip关键字添加注释、

  sed -i '/^ip/s^/#/' test.txt

4.6.将1~5行数据迁移到37行后

  sed -i '1,5{H;d};20G' test.txt

三,awk

1,awk的作用

  读取文本数据根据需要过滤关键内容

2,awk的变量

  FS:文本字段分隔符

  NF:处理行数

  NR:处理数据的行号

  $0:处理整行数据

  $n:处理数据行的第几列数据

3,awk的基本应用

3.1,awk显示文本中的内容

  awk '{print}' test.txt

3.2,显示第一列数据

  awk '{print $1}' test.txt

3.3.显示第一列和第二列数据

  awk '{print $1,$2}' test.txt

3.4.显示第一列和第二列数据使用–号分割

  awk '{print $1"———"$2}' test.txt

3.5.显示第一行和第二行数据

  awk 'NR==1,NR==2{print}' test.txt

3.6.过滤/etc/passwd的第七列数据

  awk -F ':' {'print $7'} /etc/passwd

4,应用

4.1,Ubuntu  开机自启内容

1,移动test.sh文件到/etc/init.d目录下

  mv test.sh /etc/init.d/

2,给文件增加权限

  chmod +750 test.sh

3,设置开机自动启动

  update-rc.d test.sh defaults

4.这样一个开机自动化脚本就完成咯

 5,报错解决

  1,shell脚本中报binary operator expected

    这块if [ -z $1 ]; then中的获取变量,使用双引号引起来就好了!示范:if [ -z “$1” ]; then

posted @ 2021-03-26 17:51  雅痞六爷  阅读(142)  评论(0)    收藏  举报