4、模式匹配(地址定界)
  1、空值,没有定义,默认就将文件中所有的行,放入awk进行循环
  2、对固定的 1,3 行进行操作
  sed -n '1,3p' /etc/passwd
  awk '1,3{print}' /etc/passwd  //awk默认不支持使用 1-3 1,3 等等,这样数值的直接写法;
  awk 'NR>=1&&NR<=3{print}' /etc/passwd  //通过NR变量来指定
  3、/pat1/
  sed -n /pat1/p /etc/passwd
  awk '/r..ter/{print}' /etc/passwd
   4、/pat1/,/pat2/ 第一次匹配pat1到第一次匹配pat2,之间的行
  练习:判断/^r..ter/,/^user.*\>/之间的行的用户,是bash的用户,并显示用户的用户名,和UID
  ========================================
  ?shell:
  for i in `awk '/^r..ter/,/^user.*\>/{print $NF}' /etc/passwd`;do
   if [[ $i == "/bin/bash" ]];then
    echo ``
   fi
  done
  while line;do
   if [[ "/bin/bash" == `awk -F: '{print $NF}' $line` ]];then
    awk -F '{print $1,$3}' $line
   fi
  done << `sed -n '/^r..ter/,/^user.*\>/p' /etc/passwd`
  ========================================
  awk -F: '/^r..ter/,/^user.*\>/{if($NF==/bin/bash);print $1,$3}' /etc/passwd
  5、模式匹配可以直接使用判断语句
  awk -F: '$NF=="/bin/bash"{print $1,$3}' /etc/passwd
  6、BIGEIN|END语句
  BIGEIN定义在默认循环进行操作前所要执行的语句;
  awk -F: 'BEGIN{printf "shell程序为bash的用户为:\n"}$NF=="/bin/bash"{print $1,$3}' /etc/passwd
  awk -F: 'BEGIN{printf "shell程序为bash的用户为:\n"}$NF=="/bin/bash"{print $1,$3}END{printf "end\n"}' /etc/passwd
  一般在格式化输出的时候,打印表头和表未;
  
 5、操作符
  运算操作符:
   + - * / %(取余、取模) ^ //(取整)
  比较运算符:
   == != > < >= <=
   ~ !~
  awk -F: '$NF~"/bin/bash"{print $1,$3}' /etc/passwd
  awk -F: '$NF!~"/bin/bash"{print $1,$3}' /etc/passwd
  逻辑操作符:
   &&
   ||
   !
  赋值操作符:
   =  +=  -=  /=   *=  %=  ^=   //=
  条件表达式:
   条件语句?条件成立语句:条件不成立的语句
  awk '/^title/{FN<=2? print: printf "参数过\n"}' /boot/grub/grub.conf  //有点问题 
 6、常见action
  print printf 以及 它任何命令的操作都是 action;
  1、expressions 常见表达式
  2、control statement 控制语句  例如: if while等
   逻辑关系语句判断来进行结合
  3、组合语句 compound statements
   /pat1/{{  }{  ;  }}
  4、input statements 输入语句
  5、output statements 输出语句
 *7、常见语言(if while do for break continue delete switch)
  1、if语句
   语法格式:if(条件表达式) {执行语句}
    if(条件表达式) {执行语句} else {执行语句}
  awk '/^title/{if(NF<=2) {print}else {print "参数过少"}}' /boot/grub/grub.conf
  awk '/^title/{if(NF>=2) print $4}' /boot/grub/grub.conf
  
  2、while语句
   只有对行参数进行遍历的时候才会使用循环;
   语法格式:while(条件表达式) {循环体}
  练习:过滤grub.conf文件中kernel这一行,然后对每一个参数的字符个数进行统计,并显示出来;
   初始值
   while 条件判断;do
    循环体
    初始控制语句
   done
  awk '/^[[:space:]]*kernel\>/{i=1;while(i<=NF){printf $i"\t";print length($i);i++}}' grub.conf
  
  3、for语句
   语法格式:for(初始值;条件判断;初始值控制语句){循环体}
  awk '/^[[:space:]]*kernel\>/{for(i=1; i<=NF; i++){printf $i"\t"; print length($i)}}' grub.conf
   循环建议使用for语句
  
   在awk中,for也可以使用和 shell 中一样的格式:
   回顾:
    for i in 列表;do
     循环体
    done
   
   for(i in 列表){循环体}
   echo "xia  liang z shi k hen  n shuai   da fa le " | awk '{for(i in {1..NF}) { ls=() if(length(ls[i])<=3){print $i}}}' 
   shell
   ===================================== 
    ls=(xia  liang z shi k hen  n shuai   da fa le)
    for i in `seq 0..${$ls[*]}`;do
     if [[ ${#${ls[$i]}} <= 3 ]];then
      print ls[$i]
     fi 
    done
   =====================================
  4、do-while 循环
   语法:do {循环体} while (循环条件)
   注意和while的却别:while语句只有在满足条件的时候,才会进入循环,而do while会先执行循环体(一次),在进行条件判断;
  5、循环跳出语句
   break [n]  跳出n次循环;
   continue   跳出本次循环;
   next  跳出默认的当前循环;
  awk '{if(NR%2==1) {next} else {print}}' /etc/passwd
  6、switch 类似于case
   语法格式:switch(expression){case VALUE1 or /REGXP/: statement; case VALUE2 or /REGEXP2/:statement; … ,default: statement}
    switch(表达式){case 模式匹配值:执行语句;case 模式匹配值:执行语句,...,default:执行语句}  文件
   shell:
    case 变量 in
    pat1)
     执行语句
     ;;
    *)
     执行语句
     ;;
    esac
 *8、数组*
  在awk中,数组和shell中的数组特性相同:
   注意:awk中数组不用定义,只要使用了,就有值为空的默认数组;这在做数据统计的时候非常常见!!!!!
  行遍历 -->  实际上就是整个文件的遍历
  列遍历 --> 取对象固定某列的中的,相同数据的统计
   注意:数组通过for语句,再给其他变量进行赋值的时候,赋值的是index索引信息;
  
  练习:统计一下某个文件中指定行中单词出现的次数;
  awk -v RS=" " {print} a.txt | awk '{ls[$1]++}END{for(i in ls){print i,ls[i]}}'
  练习:统计一下一个文件中每个单词(以空格隔开的字符串)出现的次数;
  awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
  awk '{for(i=1;i<=NF;i++){ls[$i]++}}END{for(j in ls){print j,ls[j]}}' /var/log/httpd/access_log | sort -t" " -k2 -nr
 9、函数
  1、内置函数
   函数的调用:funcation(参数)
   length()  统计字符串长度
   数学运算上使用的行数 sin() cos() ...
   sub(x,x,x)   替换第一个匹配到的值
  awk '{print sub(o,O,$1)}' /etc/fstab  //将o 替换为 O 文件中的 第一列(第一个匹配值)
   gsub(x,x,x)    替换该行所匹配到的所有值
  awk '{print gsub(o,O,$1)}' /etc/fstab  //将 o 替换为 O 文件中的 第一列(全部匹配值)
   split(x,x,x)   指定分隔符去切割文件
   netstat -tan | awk '/^tcp\>/{split($5,ip,":");print ip[1]}'
   netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'
  2、自定义函数

rand()  随机函数,产生0-1之间的随机小数,可以改变随机数的大小,如:rand()*10 ,rand()*5  这样可以让函数产生我们需要的随机数段,

toupper()小写转大写,tolower()大写转小写

substr()字符串截取 substr("123456789",1,2)从第一位开始截取,截取2位

“sum=$(fsum 2 5)”这种方式,是将标准输出(echo 出来的东子)传递给主程序的变量,而不是返回值!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
function sum(){
 
 val1=$1
 
 val2=$2
 
 val3=$(($1+$2))
 
 echo $val3
 
}
 
#Call function with 2 parameters and it return 1 parameter.
ret_val=$(sum 10 20)
echo $ret_val

  脚本执行结果: ret_val = $(sum 10 20)  将sum 10 20 的输出传递给变量ret_val

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
prod=1
twoPow(){
        for((i=0;i<$1;i++));
        do
                prod=$(($prod*2))
        done
}
echo "Enter a number"
read num
twoPow $num
echo $prod

  执行脚本 c.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
 
twoPow()
{
    prod=1
    for((i=0;i<$1;i++));
    do
        prod=$(($prod*2))
    done
    return $prod
}
 
echo "Enter a number"
read num
twoPow num

  

----------------------------------------------------------------------------------------------------------------------------------

Shell的函数在使用之前必须先定义,定义格式:

1
2
3
4
5
[ function ] funname [()]
{
    action;
    [return int;]
}
  • 可以带function fun()定义,也可以直接fun() 定义,不带任何参数。
  • 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)

示例

1
2
3
4
5
6
7
8
9
10
fsum 2 5
 
fsum(){
    echo $1,$2
    return $1+$2
}
 
sum=$(fsum 2 5)
echo $?
echo "sum=$sum"

执行输出:

fsum: not found
7
sum=2,5

从上面这个例子我们可以得到几点结论:

  • 必须在调用函数地方之前,声明函数,shell脚本是逐行运行,这点和编译型语言不通。
  • 函数返回值,只能通过$? 系统变量获得,而“sum=$(fsum 2 5)”这种方式,是将标准输出传递给主程序的变量,而不是返回值!

Shell函数可以在脚本文件中使用之前定义它,也可以把函数定义在一个独立的文件使用点号(.)命令来引用它。如function.sh和testshell.sh在同一目录中,function.sh

1
2
3
4
fsum(){
    echo $1,$2
    return $(($1+$2))
}

testshell.sh

1
2
3
#! /bin/sh
. ./function.sh
fsum 2 5

 

最新文章

  1. wampServer图标为橙色无法启动原因之一
  2. Android--多媒体操作
  3. Windows 系统下Git安装图解
  4. 一个十年java程序员的心得
  5. js 遮罩层 loading 效果
  6. [3D]绘制线
  7. python 小技巧(import模块、查询类继承关系、安装包)
  8. tomcat下jndi的三种配置方式
  9. Razor与ASPX语法比较
  10. 生成mif文件的几种方法总结
  11. facebook分块加载,页面优化,BigPipe,简单实例
  12. VS2015操作Oracle数据需要做那些设置?
  13. 一则 ORA-00471 处理方法
  14. java+js实现完整的图片展示本地目录demo
  15. BigInteger和BigDecimal的练习
  16. MySQL 8.0.12 基于Windows 安装教程(超级详细)
  17. 【DevExpress】邮箱制作小结
  18. VMare Workstation 12 安装 AsteriskNow freePBX
  19. cookie方法封装
  20. codeforces 1141G Privatization of Roads in Treeland

热门文章

  1. C语言程序设计(六) 循环控制结构
  2. Logitech k480 蓝牙键盘连接 ubuntu 系统
  3. lesson01
  4. 2019-2020-2 20174313张博 《网络对抗技术》Exp1 PC平台逆向破解
  5. java常用日期类总结
  6. Redhat 线下赛 WEB WP
  7. 阅读了这三篇文章,你也就基本理解了ASP.NET Core MVC框架的工作原理
  8. Python第五章-内置数据结构02-列表
  9. 强化学习之三:双臂赌博机(Two-armed Bandit)
  10. OpenCV-Python 直方图-4:直方图反投影 | 二十九