shell 脚本编程

shell 脚本编程


1. 变量的高级使用

  1. 变量删除替换
  1. ${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除
  2. ${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除
  3. ${变量名%匹配规则} 从变量尾部进行规则匹配,将符合最短的数据删除
  4. ${变量名%%匹配规则} 从变量尾部进行规则匹配,将符合最长的数据删除
  5. ${变量名/旧字符串/新字符串} 第一个旧字符串会被替换
  6. ${变量名//旧字符串/新字符串} 全部旧字符串会被替换
[node01@node01 ~]$ veriable_1="I love you,Do you love me"
[node01@node01 ~]$ echo $veriable_1
I love you,Do you love me
[node01@node01 ~]$ ver1=${veriable_1#*ov}
[node01@node01 ~]$ echo $ver1
e you,Do you love me
[node01@node01 ~]$ ver2=${veriable_1##*ov}
[node01@node01 ~]$ echo $ver2
e me
[node01@node01 ~]$ ver3=${veriable_1%ov*}
[node01@node01 ~]$ echo $ver3            
I love you,Do you l
[node01@node01 ~]$ ver4=${veriable_1%%ov*}
[node01@node01 ~]$ echo $ver4
I l
[node01@node01 ~]$ ver5=${veriable_1/love/LOVE}
[node01@node01 ~]$ echo $ver5
I LOVE you,Do you love me
[node01@node01 ~]$ ver6=${veriable_1//you/YOU}
[node01@node01 ~]$ echo $ver6                 
I love YOU,Do YOU love me
  1. 字符串处理
    1. ${#string} 获取string的长度
    2. expr length “$string" 获取string长度,有string有空格,需要加” “
    3. expr index $string $substring 获取substring在string的索引 获取字符的位置
    4. expr match $string substr 获取子串的长度
    5. ${string:position} 从string中的position开始匹配,所以从0开始
    6. ${string:position:length} 从position开始匹配,匹配长度length
    7. ${string:-position} 从右开始匹配
    8. ${string:(position)} 从左开始匹配
    9. expr substr $string $position $length 从position开始匹配,匹配length长度,索引从1开始
    [node01@node01 ~]$ veriable_1="I love you,Do you love me"
    [node01@node01 ~]$ echo ${#veriable_1}
    25
    [node01@node01 ~]$ echo `expr length "$veriable_1"`
    25
    [node01@node01 ~]$ string="love"
    [node01@node01 ~]$ echo `expr index "$veriable_1" "$string"`
    3 #实际找的是love中l在veriable_1中的位置
    [node01@node01 ~]$ echo `expr index "$veriable_1" five`
    5 #返回的是v的索引位置
    [node01@node01 ~]$ expr match "$veriable_1" you
    0
    [node01@node01 ~]$ expr match "$veriable_1" I
    1 #必须从头开始获取,否则返回0
    
    [node01@node01 shell]$ ver1="kafka hadoop yarn mapreduce"
    [node01@node01 shell]$ substr1=${ver1:10}
    [node01@node01 shell]$ echo $substr1     
    op yarn mapreduce #索引下标从0开始
    [node01@node01 shell]$ echo "${ver1:10:5}"
    op ya
    [node01@node01 shell]$ echo "${ver1: -5}"#冒号后要加空格
    educe
    [node01@node01 shell]$ echo "${ver1:(-5)}"
    educe
    [node01@node01 shell]$ echo "${ver1:(-5):2}"
    ed
    [node01@node01 shell]$ echo `expr substr "$ver1" 10 5`
    oop y #索引从1开始
    
    
  2. 命令替换
    1. cmmond

      #`command`
        1 #!/bin/bash
        2 index=0
        3 for user in `cat /etc/passwd | cut -d ":" -f 1`
        4 do 
        5     echo "This is "$index" user "$user""
        		index=$((index + 1))
        6 done
      
    2. $(commond)

      [node01@node01 ~]$ echo "This is $(date +%Y)"  
      This is 2019
      [node01@node01 ~]$ echo "This is $(($(date +%Y) + 1))"
      This is 2020
      #$(date +%Y) 是执行命令
      #(($(date +%Y) + 1) 执行算数运算
      #$(($(date +%Y) + 1)) 输出变量结果
      

      注意

      1. $( date ) 是执行date命令,等同于两个反引号``

      2. ${date} 是获取date变量 的值,或者用作变量替换,如${$string#$str}

      3. $[]或者$(()) 是用于数学运算

        ​ $(($(date +%Y) + 1)) 等价于$[$(date +%Y) +1] 结果都是2020

      4. : 即为test命令的另一种形式。

      但要注意许多

      1.你必须在左括号的右侧和右括号的左侧各加一个空格,否则会报错。

      2.test命令使用标准的数学比较符号来表示字符串的比较,而用文本符号来表示数值的比较。很多人会记反了。使用反了,shell可能得不到正确的结果。

      3.大于符号或小于符号必须要转义,否则会被理解成重定向。

      (( ))及[[ ]]

      它们分别是[ ]的针对数学比较表达式和字符串表达式的加强版。

      其中(( )),不需要再将表达式里面的大小于符号转义,除了可以使用标准的数学运算符外,还增加了以下符号:

      var++	后增
      var--	后减
      ++var	先增
      --var	先增
      !		先减
      ~		逻辑求反
      **		幂运算
      <<		左位移
      >>		右位移
      &		位布尔和
      |		位布尔或
      &&		逻辑和
      ||		逻辑或
      
  3. 变量类型

    declear :

    于typeset等价。

    • -r 只读

      [node01@node01 ~]$ declare -r num="hello workd"
      [node01@node01 ~]$ num="hello"
      -bash: num: readonly variable
      
    • -i 整数

      num1=10
      num2=$[$num1 + 10]
      
    • -a 数组

    • -f 显示定义过得所有函数及内容

    • -F 显示定义过得函数名

    • -x 将变量声明为环境

  4. expr使用
    • 方法一: expr $num1 operator $num2
  • 方法二: $((num1 operator num2))

     num1 | num2 	num1不为空且非0,返回num,否则返回num2
     num1 & num2    num1不为空且非0,返回num,否则返回0
     num1 < num2     num1小于num2,返回1,否则返回0
     num1 <= num2     num1小于等于num2,返回1,否则返回0
     num1 = num2     num1等于num2,返回1,否则返回0
     num1 != num2     num1不等于num2,返回1,否则返回0
     num1 > num2     num1大于num2,返回1,否则返回0
     num1 >= num2     num1大于等于num2,返回1,否则返回0  
    
     num1 + num2 求和
     num1 - num2 求差
     num1 * num2 求积
     num1 / num2 求商
     num1 % num2 求余
    
    num1=30
    num2=50
    expr $num1 \| $num2 #结果为30,$num1和$num2之间要有空格
    expr $num1 \& $num2 #结果为10
    expr $num1 \> $num2 #返回0
    expr $num1 \< $num2 #返回1
    
    expr $num1 + $num2	#返回80
    expr $num1 - $num2  #返回-20
    expr $num1 \* $num2	#返回1500
    expr $num1 / $num2	#返回0
    expr $num1	% $num2 #返回
    

    判断一个数是否数正整数

    #!/bin/bash
    
    expr $num1 + 1 &> /dev/null #如果num不是一个整数,则命令执行不成功。expr只能进行整数运算,命令运行出错时,$?会是一个非零的数
    if [ $? -eq 0 ];then
    	if [ `expr $num \> 0` -eq 1 ];then
    		echo "num 是一个正整数"
    	else	
    		echo "num 不是一个正整数"
    	fi
    fi
    
  1. bc 浮点数操作

    bc可以支持加减乘除(±*/)外,还支持求余(%),指数运算(^),有一个内建参数scale设置精度

    echo " scale=4;23/35" | bc
    

2. 函数的高级用法

​ 1. 不做特殊声明,都是全局变量。

​ 2. 要声明局部变量,要用local修饰

​ 3. 函数返回值,echo 返回数字字符串, return 返回 1~ 255 数字;

  1. 函数返回值

    1. return 返回值,只能返回1-255
    	通常只是用来供其他地方调调用获取状态。因此通常返回0或1,0代表成功,1代表失败。
    2. echo返回值,可以返回任何字符串
    	通常用于返回数据,比如一个字符串值或者列表值。
    
      1 #!/bin/bash
      2 
      3 num1=10
      4 num2=20
      5 
      6 function compare
      7 {
      8     if [ $num1 -lt $num2 ];then
      9         return
     10     else
     11         return 1
     12     fi
     13 }
     14 
     15 compare && echo "num1 less then num2" || echo "num1 greater then num2" 
     
     [node01@node01 831]$ ./return_1.sh 
     um1 less then num2
    
    #!/bin/bash
    
    function get_users
    {
            users=`cat /etc/passwd | cut -d: -f1`
            echo $users
    }
    
    user_list=`get_users` #将返回值赋值给user_list
    for user in $user_list
    do
            echo $user
    done
    
  2. 全局变量和局部变量

    不做特殊声明,全部都是全局变量,即使在函数中的变量,被赋值后,也变成了全局变量。

    在写大型项目是,慎用全局变量。

    定义局部变量时,用local关键字。

    函数内部变量,存在于外部同名的变量时,内部变量覆盖外部变量。

    #!/bin/bash
    
    str="hello world"
    
    function echo_str
    {
            var2=86
            local var3=87
    }
    echo $str #hello world
    echo $var2 #空
    echo $var3 #空
    
    echo_str
    
    echo $str #hello world
    echo $var2 #86
    echo $var3 #空
    
  3. 函数库

    • 库文件的后缀是任意的,但一般用.lib
    • 库文件没有可执行权限
    • 库文件一般放在 /lib 目录下
    • 第一行一般使用 #!/bin/echo 输出警告信息 ,以避免用户执行
    base_function
    #!/bin/echo
    function add
    {
    	echo "`expor $1 + $2`"
    }
    
    add.sh
    #!/bin/bash
    . base_function
    
    add 10 20
    

3. 文件查找命令高级用法

  1. find 命令

    从磁盘根据选项来查询文件,缺点是速度比较慢。

    语法格式:find [路径] [选项] [文件名]

    • -name 根据文件名
  • -iname 忽略大小写
   find /etc -name "*.conf"
find /etc -iname "aa" #aa,AA,Aa,aA都可以搜索到
  • -perm 根据文件权限
find /etc -perm 644
  • -prune 排除某些查找目录

通常与-path一起使用,用于将特定的目录排除掉

  • -user 根据文件属主
   find ./ -user hdfs
  • -group 根据文件组
find ./ -group yarn
  • -mtime -n | +n 根据修改时间 天(非常常用)
find /etc -mtime -3 #三天之内修改的文件
find /etc -mtime +3 -name “*.conf” #三天前修改的,以.conf结尾的文件

非常用选项

  • -mmin +n|-n 在分钟之前修改的
find /etc -mmin +30  #三十分钟之前修改的文件 
find /etc -mmin -30  #三十分钟之内修改的文件 
  • -type 根据文件类型
find ./ -type f	#普通文件
find ./ -type d	#目录
find ./ -type c	#字符设备文件
find ./ -type b	#块设备文件
find ./ -type l	#链接文件
find ./ -type p	#管道文件
  • -nogroup 查找无有效属组的文件

  • -nouser 查找无有效属主文件

  • -mindepth n 从n级子目录开始搜索

find /etc -mindepth 3 -name ".conf" #从三级子目录开始搜索
  • -maxdepth n 最多搜索到n级子目录
find /etc -maxdepth 3 -name ".conf" #最多搜索到三级目录
  • -size -n +n 根据文件大小
find /etc -size +1M #所有大于1M的文件
find /etc -size -100K #所有小于100K的文件
  • -print 把结果打印出来(默认)

  • -exec:(非常重要的)

  • -ok 和-exec是一样的。

    -exec ‘common’ { } ;

     	eg: find ./ -name "\*.txt"  -exec rm -rf {} \; 
     	find ./ -name "\*.txt" -exec cp {} ./test \;
    
2. locate

使用场景:属于软件包mlocate,不同于find在整块磁盘搜索,locate只在数据库文件中查找

系统的定时任务更新数据库。find是默认全部匹配,locate是默认部分匹配。

执行updatadb命令可以实时更新locate数据库

3. whereis

-b 返回二进制文件

-m 返回帮助文档

-s 返回源代码文件

4. 文本处理grep sed awk

1. grep过滤器
  • 用法

    • grep [option] pattern file

      • command | grep option pattern
  • 参数

    • -v 不显示匹配行信息
    • -i 忽略大小写
    • -n 显示行号
    • -r 递归搜索
    • -E 支持扩展正则表达式
    • -F 不按正则表达式匹配,按照字符串字面意思匹配
    • -c f符合条件的行数 统计字符串个数
    • -w 匹配整词
    • -x 匹配整行
  • egrep

    • 支持正则表达式,等价于grep -E
    grep -E "py.*"  ./ #支持正则表达式
    
2. sed 流编辑器

用法:sdout | sed [option] “pattern command” 或者 sed [option] “pattern command” file

  1. -n 只打印模式匹配行,不打印其他信息
  2. -e 直接在命令行进行sed编辑,默认选项,执行多个命令时用到
  3. -f 编辑命令所在的文件
  4. -r 支持正则表达式
  5. -i 直接修改文件
sed -n '/root/p' passwd #只对匹配到的行进行打印
sed -n -e '/root/p' -e '/sbin/p' passwd #执行多个命令
sed -n -f edit.sed passwd #edit.sed 里面记录的是命令,' '中包含的内容,例如:/root/p
sed -n -r '/root|sbin/p' passwd #打印出包含root或sbin的内容
sed -i 's/root/ROOT/g' passwd #-i 不能与-n一起使用
1. 常用编辑命令(也就是command)
  1. p 打印

    sed -n '/root/p'   打印出匹配到的root 的行
    
  2. a 行后追加

    sed -i  ‘/root/a this is user which can login the system’
    #匹配到/bin/bash 的行,把这句话插入到后面
    
  3. i 行前追加

    sed -i ’/^hdfs/,/^yarn/i  AAAAAAAAAAAAAAAAAAAa’  file
    #以hdfs开头到yarn开头的行 的行前追加 AAAAAAAAAAAAAAAa
    
  4. r 外部文件读入,行后追加

    sed -i ‘/root/r list’ passwd
    #读取list中的内容,追加到passwd中,含有root的行后面
    
  5. 、w 匹配行写入外部文件

    sed -n ‘/\/bin\/bash/w  /tmp/user_login.txt’ passwd
    #把所有匹配到的/bin/bash的行写到user_login.txt中
    
  6. g 行内全部替换 ;2g 从第二个开始,全部匹配 ; 2 替换第二个;ig 匹配后不区分大小写

    s/pattern/string/(1,2,3,4,5..….)
    #将匹配到的pattern替换为string,默认只替换一个(1,2 ,3,4,5..…)
    
    s/pattern/string/g
    #把匹配到的行中,将匹配到的pattern全部替换为string
    
    s/pattern/string/2g
    #把匹配到的行,从第二个pattern开始全部替换string
    
    s/pattern/string/ig  
    #把匹配到的pattern,不管是大写还是小写,全部替换为string
    
  7. = 显示匹配到的行号

    [node01@node01 ~]$ sed -n /root/= /etc/passwd
    1
    11	
    
2. 反向引用
sed -i  \'s/had..p/\$s/g’  str.txt  
#对匹配的值,后添加s
sed -i ‘s/(had..p)/\1o’ str.txt
#使用\1时需要把had..p用小括号括起来。
sed -i ‘s/\(had\)..../\1doop/g’ str.txt
#had不变,把后面的..….匹配到的字符,替换为doop。
3. 修改命令
  1. 1s/old/new/ 替换第一行的第一个内容old为new,加g就是所有的都替换
  2. 1,10s/old/new/ 替换第一到十行的内容old为new
  3. 1,+5s/old/new/ 替换1到6行内的内容old为new
  4. /pattern1/s/old/new/ 替换匹配到pattern1的内容的行的old为new
  5. /pattern1/,/pattern2/s/old/new/ 替换匹配到pattern1的内容的行直到pattern2的行的old为new
  6. /pattern1/,10s/old/new/ 替换匹配到pattern1的行,到10行的内容的old为new
  7. 10,/pattern1/s/old/new/ 匹配第10行,到pattern1的行的内容old为new
sed 
4. 匹配模式
  1. 10command 匹配第10行
  2. 10,20command 匹配从10行开始到20行结束
  3. 10,+5command 匹配从10行开始到第16行结束
  4. /pattern1/command 匹配到pattern1的行
  5. /pattern1/,/pattern2/command 匹配到pattern1的行开始,到pattern2行结束
  6. 10,/pattern1/command 匹配从第10行开始,到匹配pattern1行结束
  7. /pattern1/,10command 匹配从pattern1的行开始,到第10行结束
 sed -n '10p' passwd #打印第10行信息
 sed -n '2,4p' passwd #打印第二行到第四行信息,一共打印3行信息
 sed -n '1,+5' passed #打印第一行,加上后面的五行,一共6行
 sed -n '/root/p' passwd #打印有root的行
 sed -n '/^root/,/^uucp/p' passwd #打印以root为开头的行,到以uucp为开头的行
 sed -n '4,/^uupc/p' passwd #从第四行的下一行开始匹配,当uupc的行是第四行时,会打印从uupc开始到文件结尾的所有信息,如果uupc的行号小于4,则打印第4行,到文件结尾的所有信息。(如果文件只有一处uucp)
 sed -n '/root/,10p' passwd #从root开始接下来的9行,一共10行
5.引用变量
sed -i “s/\$old_str/\$new_str/g” str.txt
#在引用变量时,需要使用双引号
sed -i ’s/’\$old_str’/’\$new_str’/g‘  str.txt
#也可以用单引号将变量括起来
3.awk 报告生成器

文本处理工具,通常用于处理数据并生成结果报告。

语法:
awk ’BEGIN{} ptttern{commands}END{}‘ file_name
stdout | awk ‘BEGIN{}pattern{commands}END{}’ file_name

BEGIN{} 正式处理前执行
pattern	匹配模式
{commands}	处理命令,可能多行
END{}		处理完所有匹配数据后执行
1. awk的内置变量
  1. $0 整行内容
  2. $1-$n 当前行的1-n个字段
  3. NF (number field) 当前行的行号,从1开始计数
  4. NR (number row) 当前行的行号,从1开始计数
  5. FNR (filed number row ) 多文件处理时,每个文件单独计数,从0开始
  6. FS (field separator) 输入字符分隔符,不指定默认以空格或tab做为分隔符
  7. RS (row separator)输入行分隔符,默认为回车
  8. OFS (output field separator) 输出字符分隔符,默认为空格
  9. ORS (output row separator) 输出行分隔符,默认为回车
awk '{print $0}' /etc/passwd #输出全部的passwd内容
awk '{print $1}' /etc/passwd #什么都指定,默认以空格和tab为分隔符
awk 'BEGING{FS=":"}{print $1}' /etc/passwd #输出passwd中以:分隔符的第一个字段
awk 'BEGIN{FS=":"}{print NF}' passwd #以“:”作为分隔符,看每一行有多少个字段
awk '{print NR}' passwd ./sed.txt #passwd和sed.txt 每个文件单独计数行号
awk '{print FNR}' passwd ./sed.txt #passwd和sed.txt 每个文件单独计数行号
awk 'BEGIN{FS=":"}{print $1}' passwd #指定分隔符
awk 'BEGIN{ORS="="}{print $1}' passwd #指定行分隔符
awk 'BEGIN{FS=":"OFS="="}{print $1,$3}' passwd#以“:”为分隔符,将第一个字段和第三个字段用“=”连接起来

awk 'BEGIN{FS=":"}{printf "%-20s %-20s\n",$1,$2}' passwd #以“:”为分隔符,将第一个和第二个字段,以20位,以左对齐输出
  1. awk 匹配模式的两种用法

    第一种模式匹配:直接使用正则表达式

    ​ 支持正则表达式

    第二章模式匹配:关系运算符

    ​ 支持的运算符:

    <	小于
    >	大于
    <=	小于等于
    >=	大于等于
    ==	等于,可以用于比较字符串
    !=	不等于
    ~	匹配正则表达式
    !~	不匹配正则表达式
    
    ||&&  与
    !	非
    

awk ‘BEGIN{FS=":"}/root/{print $0}’ passwd#输出所有包含root字符串的行
awk ‘BEGIN{FS=":"}/^root/{print $0}’ passwd #输出包含以root开头的行
awk ‘BEGIN{FS=":"}$3<50{print $0}’ passwd #输出以:为分隔符的字段,如果大于50就输出
awk ‘BEGIN{FS=":"}$7=="/bin/bash"{print $0}’ passwd#比较字符串
awk ‘BEGIN{FS=":"}$3~/[0-9]{3,}{print $0}’ passwd#输出第一个字段,包含三个数字以上的
awk ‘BEGIN{FS=":"}$3!~/[0-9]{3,}{print $0}’ passwd#输出第一个字段,不包含三个数字以上的

awk ‘BEGIN{FS=":"}$1==“root”||$1=“node01”{print $0}’ passwd #输出包含root或node01的行
awk ‘BEGIN{FS=":"}$3<30 && $4>50 {print $0}’ passwd #输出字段三小于30,字段4大于50的行

3. awk 的算术运算符

可以执行加减乘除

awk 'BEGIN{var=20;var=30;printf "%0.2f\n",var+var1}'
awk 'BEGIN{var=20;var+=30;printf "%0.2f\n",var}'
awk '/^root/{sum++}END{print sum}' passwd

Allen	80	90	96	98
Mike	93	98	92	91
Zhang	78	76	87	92
Jerry	86	89	68	92
Han		85	95	75	90
Li		78	88	98	100
[node01@node01 ~]$ awk '{total=$2+$3+$4+$5;AVG=total/4;printf "%-8s%-5d%-5d%-5d%-5d%-0.2f\n",$1,$2,$3,$4,$5,AVG}' student.txt
Allen   80   90   96   98   91.00
Mike    93   98   92   91   93.50
Zhang   78   76   87   92   83.25
Jerry   86   89   68   92   83.75
Han     85   95   75   90   86.25
Li      78   88   98   100  91.00
[node01@node01 ~]$ awk 'BEGIN{printf "%-8s%-5s%-5s%-5s%-5s%-5s\n","名字","语文","数学","物理","英语","AVG"}{total=$2+$3+$4+$5;AVG=total/4;printf "%-8s%-8d%-8d%-8d%-8d%-0.2f\n",$1,$2,$3,$4,$5,AVG}' student.txt    
名字      语文   数学   物理   英语   AVG  
Allen   80      90      96      98      91.00
Mike    93      98      92      91      93.50
Zhang   78      76      87      92      83.25
Jerry   86      89      68      92      83.75
Han     85      95      75      90      86.25
Li      78      88      98      100     91.00
4. awk 条件循环语句
1.条件语句
if(condition)
	active1
else if
	active2
else
	avtive3
awk 'BEGIN{FS=":"}{if($3>50 && $3<100) print $0}' passwd #字段大于50并且小于100的所有行

awk 命令写入脚本,使用 -f 导入到命令中

#scrips.awk 
BEGIN{
	FS=":"
}

{
	if($3<50)
 	{
 		printf "%-40s%-40s%-5d\n","小于50的UUID",$1,$3                                                   
 	}
}
#执行命令:
[node01@node01 ~]$ awk -f scrips.awk passwd 
小于50的UUID           root                0    
小于50的UUID           bin                 1    
小于50的UUID           daemon              2    
小于50的UUID           adm                 3    
小于50的UUID           lp                  4    
小于50的UUID           sync                5    
小于50的UUID           shutdown            6    
小于50的UUID           halt                7    
小于50的UUID           mail                8    
小于50的UUID           uucp                10   
小于50的UUID           operator            11   
小于50的UUID           games               12   
小于50的UUID           gopher              13   
小于50的UUID           ftp                 14
2. while
#语法
do{
	active1
}
while(condition)

while(condition){
	active1
}
#1~100的和
#scrip.awk
BEGIN{
	while(i<100)
	{
		 sum+=i
		 i++
	}
	print sum
}
awk -f scrip.awk
5050

[node01@node01 ~]$ awk 'BEGIN{while(i<=100){sum+=i;i++};print sum}'
5050
3. for
#语法
for(初始化;条件判断;条件变化)
	active
#1~100
#scrip.awk
BEGIN{
	for(i=0;i<=100;i++)
	{
		sum+=i
	}
	print sum
}
awk -f scrip.awk
5. awk 字符串函数
length(str)			计算字符串长度						返回整数长度
index(str1,str2)	在str1中查找str2的位置				返回位置索引,从1开始
tolower(str)		转换为小写							转换后的小写字符
toupper(str)		转换为大写							转换后的大写字符
substr(str,m,n)		从str的m个字符位置开始,截取n位		截取后的子串
split(str,arr,fs)	按fs切割字符串,结果保存arr		切割后的子串个数
match(str,RE)		str中按照RE查找,返回位置			返回索引位置

sub(RE,RepStr,str)	在str中查找符合正则表达式的子串,并替换为RepStr,只替换第一个 返回替换的个数
gsub(RE,RepStr,str)在str中查找符合正则表达式的子串,并替换为RepStr,替换所有 返回替换的个数
#length.awk
BEGIN{
	FS=":"
}
{
	i=1
	while(i<=NF)
	{
		if(i==NF)
			printf "%d",length($i)
		else
			printf "%d:",length($i)
		i++
	}
}

awk -f length.awk passwd
[node01@node01 ~]$ awk 'BEGIN{str="i have a dream";printf "%d\n",index(str,"ea")}'
12			#使用index()计算子串位置
[node01@node01 ~]$ awk 'BEGIN{str="i have a dream";printf "%d\n",match(str,"ea")}'
12			#使用match()查找子串位置
[node01@node01 ~]$ awk 'BEGIN{str="Hadoop ia a big data framwork";printf "%s\n",tolower(str)}'
hadoop ia a big data framwork

[node01@node01 ~]$ awk 'BEGIN{str="Hadoop ia a big data framwork";printf "%s\n",toupper(str)}'
hadoop ia a big data framwork #全部转为小写

[node01@node01 ~]$ awk 'BEGIN{str="Hadoop ia a big data framwork";printf "%s\n",toupper(str)}'
HADOOP IA A BIG DATA FRAMWORK	#全部转为大写
[node01@node01 ~]$ awk 'BEGIN{str="Hadoop ia a big data framwork";split(str,arry_1," ");for(a in arry_1) print arry_1[a]}'
big
data
framwork
Hadoop
ia
a
 awk 'BEGIN{str="Tranction 2345 Start:Select * from master";print match(str,/[0-9]/)}'  #结果为11
[node01@node01 ~]$  awk 'BEGIN{str="Tranction Start";print substr(str,4,5)}' 
nctio #截取到的str
[node01@node01 ~]$ awk 'BEGIN{str="Tranction 2345 Start:Select * from master 1231";print sub(/[0-9]+/,"$",str);print str}' 
1	#替换个数
Tranction $ Start:Select * from master 1231 #替换完的str

[node01@node01 ~]$ awk 'BEGIN{str="Tranction 2345 Start:Select * from master 1231";print gsub(/[0-9]+/,"$",str);print str}'
2
Tranction $ Start:Select * from master $  #gsub()替换所有的子串
6. awk 选项总结
-v	传递参数
-f	指定脚本文件
-F	指定分隔符
-V	查看awk的版本
[node01@node01 ~]$ num=20
[node01@node01 ~]$ var="hello workd"
[node01@node01 ~]$ awk -v num1="$num" -v var2="$var" 'BEGIN{print num1,var2}' #引入参数
20 hello workd
awk -F: '{print $7}'
awk -F ':' '{print $7}'
awk -V #查看版本
7. awk 数组的使用
1.shell中数组的使用方法
shell中数组的用法
arry=("alen","mike","lilei","jerry","wang")
echo ${arry[0]}		#访问数组元素
echo ${#arry[@]}	#求数组元素个数
echo ${#arry[*]}	#求数组元素个数
echo ${#arry[1]}	#求数组元素长度
str="hello"
echo ${#str}		#求字符串长度
arry[0]="lili"		#给数组赋值
unset arry[0]		#删除元素
unset arry			#清空所有元素
[node01@node01 ~]$ arry=("lilei" "mark" "jerry" "tty")  
[node01@node01 ~]$ echo ${arry[0]}                    
lilei
#删除元素时,元素一直使用原有的下标

echo ${arry[@]:1:3} #从1开始访问到3
${arry[@]/e/E}  	#只替换元素第一个e
${arry[@]//e/E}		#替换元素里面全部的e

for a in ${arry[@]}
do
	echo $a
done #遍历数组里面所有的元素
2. awk中数组的使用方法
#awk中数组的使用
netstat -an | grep tcp | awk '{array[$6]++}END{for(a in arr) print a,arry[a]}'

  1. 发现数组其实是无序的,可以把它当成python中的字典.
awk` `'BEGIN{ huluwa["yiwa"]="大娃";huluwa["erwa"]="二娃";huluwa["sanwa"]="三 娃"huluwa["siwa"]="四娃";for(i in huluwa){print i,huluwa[i]} }'
siwa 四娃
yiwa 大娃
erwa 二娃
sanwa 三娃
  1. 在awk中,元素的值设置为"空字符串"是合法的,所以不能用元素值是否为空,判断该元素是否存在于数组中.
`当一个元素不存在于数组时,引用该元素,``awk``会自动创建这个元素,为这个元素赋值为空字符串,``所以引用一个不存在于数组的元素时,这个元素已经被赋值了,也就是已经存在了.``awk` `'BEGIN{huluwa[0]=``"大娃"``;huluwa[1]=``"二娃"``;huluwa[3]=``"三娃"``;huluwa[4]=``""``;``if``(5 ``in` `huluwa){print ``"第6个元素存在就能看到这句话"``}}'`
  1. 使用语法if(下标 in 数组名),可以判断数组中是否存在对应的元素.
`awk` `'BEGIN{huluwa[0]=``"大娃"``;huluwa[1]=``"二娃"``;huluwa[3]=``"三娃"``;huluwa[4]=``""``;``if``(!(5 ``in` `huluwa)){print ``"第6个元素存在就能看到这句话"``}}'``第6个元素存在就能看到这句话`

6. 监控脚本

7. MySQL数据处理

  1. 启动mysql

    #启动mysql服务器
    /data/mysql/mysql/support-files/mysql.server start|stop
    
    #初始化
    bin/mysqld --initialize --user=mysql --basedir=/data/mysql/mysql --datadir=/data/mysql/mysql/data //初始化数据库
    
     root@localhost: m(9yC.LmlNna #第一次生成的用户是root,密码是m(9yC.LmlNna
    ALTER USER 'root'@'localhost' IDENTIFIED BY 'mysql';
    
    #如果忘记密码
    在【mysqld】模块添加:skip-grant-tables
    重启mysql服务:  service mysqld restart;
    3://将旧密码置空
    mysql -u root -p    //提示输入密码时直接敲回车。
    //选择数据库
    use mysql
    //将密码置空
    update user set authentication_string = 'mysql' where user = 'mysql';
    //退出
    quit
    
    4://去除免密码登陆
    删掉步骤1的语句  skip-grant-tables
    重启服务  service mysqld restart
    
#导入数据到数据库中
msyql -u root -p -D school < school.sql
 grant all on school.* to dbuser@'%' #所有权限
  grant select on school.* to dbuser@'%' #只有查询权限
创建账户:create user '用户名'@'访问主机' identified by '密码';
赋予权限:grant 权限列表 on 数据库.*  to '用户名'@'访问主机' ;(修改权限时在后面加with grant option)

mysql> create user 'qiyun'@'%' identified by 'mysql';
Query OK, 0 rows affected (0.05 sec)
mysql> grant all on school.* to 'qiyun'@'%';
Query OK, 0 rows affected (0.06 sec)
  1. mysql 命令参数详解

    -u	#用户名
    -p	#用户密码
    -h	#服务器IP地址
    -D	#连接的数据库
    -N	#不输出列信息
    -B	#使用tab键代替默认交互分隔符
    -e	#执行SQL语句
    
    #其他选项
    -E	#垂直输出
    -H	#以HTML格式输出
    -X	#以XML格式输出
    
    

IFS="||" #shell内置的环境变量,指定字段的分隔符



3. mysql 库备份

```shell
#mysqldump
-u	#用户名
-p	#密码
-h	#服务器IP地址
-d	#只导出表结构
-t	#只导出数据
-A	#导出所有数据
-B	#导出一个或多个数据库

ftp传文件

#!/bin/bash
#
ftp -in << EOF
	open 192.168.184.3
	user ftp_user redhat
	
	cd /tmp 
	put 123
	bye
EOF

-V 提示信息
-n 自动登录,不进入命令行

8. 大型脚本编写

脚本工具功能概述:

​ 需求描述:

	1. 实现一个脚本工具,可以对进程进行管理;
	2. 一键查看所有进程运行状态
	3. 单个或批量启动进程,单个或批量停止进程
	4. 提供进程分组功能,可以按组查看进程运行状态,可以按组启动或停止改组内所有进程
  1. 拆分脚本功能, 抽象函数
    1. function get_all_process 返回进程名称列表
    2. function get_all_group 返回进程名称列表
    3. function get_process_info 返回进程信息,运行状态,pid,cpu占用率,内存占用率,启动时间
    4. function get_all_process_by_group 返回进程组内的所有进程名称列表字符串

d by ‘mysql’;
Query OK, 0 rows affected (0.05 sec)
mysql> grant all on school.* to ‘qiyun’@’%’;
Query OK, 0 rows affected (0.06 sec)


2. mysql 命令参数详解

   ```shell
   -u	#用户名
   -p	#用户密码
   -h	#服务器IP地址
   -D	#连接的数据库
   -N	#不输出列信息
   -B	#使用tab键代替默认交互分隔符
   -e	#执行SQL语句
   
   #其他选项
   -E	#垂直输出
   -H	#以HTML格式输出
   -X	#以XML格式输出
   

IFS="||" #shell内置的环境变量,指定字段的分隔符



3. mysql 库备份

```shell
#mysqldump
-u	#用户名
-p	#密码
-h	#服务器IP地址
-d	#只导出表结构
-t	#只导出数据
-A	#导出所有数据
-B	#导出一个或多个数据库

ftp传文件

#!/bin/bash
#
ftp -in << EOF
	open 192.168.184.3
	user ftp_user redhat
	
	cd /tmp 
	put 123
	bye
EOF

-V 提示信息
-n 自动登录,不进入命令行

8. 大型脚本编写

脚本工具功能概述:

​ 需求描述:

	1. 实现一个脚本工具,可以对进程进行管理;
	2. 一键查看所有进程运行状态
	3. 单个或批量启动进程,单个或批量停止进程
	4. 提供进程分组功能,可以按组查看进程运行状态,可以按组启动或停止改组内所有进程
  1. 拆分脚本功能, 抽象函数
    1. function get_all_process 返回进程名称列表
    2. function get_all_group 返回进程名称列表
    3. function get_process_info 返回进程信息,运行状态,pid,cpu占用率,内存占用率,启动时间
    4. function get_all_process_by_group 返回进程组内的所有进程名称列表字符串

等等。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值