mingche 发表于 2018-8-25 09:09:31

shell中的数组、正则表达式、sed、awk的使用

  咱有什么说什么,说实在的,这部分我感觉是liunx中最乱的地方,也是最不好学的,也是能看出人最专业的地方,明白我的意思了吧,,,,自己体会。
  数组 declare
  定义变量的类型
  declare 选项 变量名=值
  选项有
  -i整形的变量
  -r只读的变量定义就不可以修改了
  -x系统环境变量
  -a数组变量想把多个变量定义成一个组
  ---------
  # declare -i a=1 b=2
  # declare -i c=$a*$b
  # echo $c
  2
  ---------
  创建数组
  # declare -a teaname
  ----------
  查看数组
  # declare -a
  ------
  数组赋值 (添加信息)
  数组名 [元素下标]=值
  ----------
  给数组添加内容
  # teaname=yzs
  # teaname=xly
  # teaname=lili
  # declare -a
  declare -a BASH_ARGC='()'
  declare -a BASH_ARGV='()'
  declare -a BASH_LINENO='()'
  declare -a BASH_SOURCE='()'
  declare -ar BASH_VERSINFO='(="3" ="2" ="25" ="1" ="release" ="i386-redhat-linux-gnu")'
  declare -a DIRSTACK='()'
  declare -a FUNCNAME='()'
  declare -a GROUPS='()'
  declare -a PIPESTATUS='(="0")'
  declare -a teaname='(="yzs" ="xly" ="lili")'
  ------------
  # serip=(1.1.1.1 2.2.2.2 3.3.3.3)
  # declare -a |grep serip
  declare -a serip='(="1.1.1.1" ="2.2.2.2" ="3.3.3.3")'
  ---------------
  输出数组元素
  # echo ${serip}
  2.2.2.2
  输出全部元素
  # echo ${serip[@]}
  1.1.1.1 2.2.2.2 3.3.3.3
  # echo ${serip
[*]}
  1.1.1.1 2.2.2.2 3.3.3.3
  ----------
  统计数组元素的个数
  # echo ${#serip
[*]}
  3
  --------
  统计模个元素值的长度 (第一个代表0第二个代表1 1.1.1.1是7位.也算)
  # echo ${#serip}
  7
  ---------
  输出模个位置的元素从所有的数组里选取第2个元素
  # echo ${serip[@]:2}
  3.3.3.3
  ------
  # hostname=(www.baidu.com www.sina.com www.uplooking.com)
  # echo ${hostname}
  www.uplooking.com
  # echo ${hostname:0}
  www.uplooking.com
  # echo ${hostname:4}
  uplooking.com
  # echo ${hostname:4:9}从第几个开始输出 输出几位
  uplooking
  --------
  把从屏幕输入的三次IP 地址 存放到数组serip里
  把数组色日跑得三个元素值输出到屏幕上
  1 #!/bin/bash
  2 read -p "请输入第一个IP地址" a
  3 read -p "请输入第二个IP地址" a
  4 read -p "请输入第三个IP地址" a
  5
  6 echo ${a[@]}
  用循环的方式给数组赋值
  1 #!/bin/bash
  2 read -p "清输入监控主机的台数:" a
  3 i=0
  4 while [ $i -lt $a ]
  5   do
  6 read -p "清输入第一台主机ip:" serip[$i]
  7   let i++
  8   done
  9
  10
  11   echo ${serip[@]}
  用循环的方式输出数组元素
  1 #!/bin/bash
  2 read -p "清输入监控主机的台数:" a
  3 i=0
  4 while [ $i -lt $a ]
  5   do
  6 read -p "清输入第一台主机ip:" serip[$i]
  7   let i++
  8   done
  9   echo "-------------------------------------------"
  10 for i in `echo ${serip[@]}`
  11   do
  12   echo $i
  13   done
  14 echo "----------------------------------------"
  15 for ((i=0;i=oo个到多个
  + >= 1   1 个到多个
  \?是0次或1
  ***************************************************
  用grep 的时候 下面的这几个必须要转意
  ^ $ . []* \? \+ \{ \} \< >/ \| \( \)
  ****************************************************
  () 保存 匹配的模式
  (ab) 一个整体
  ^pac*j$   c出现0此或者无穷次
  ^p(ac)*j$ *前面的ac出现0此或者无穷次
  [ ] 匹配范围内的也就是任意一个
  [afb] 包括 afb里任意一个都匹配
  [a-d]只要里面的有任意一个都匹配
  [a-Z]所有的字母
  .*   表示所有字符
  [^a-c] ^在[]表示取反没有a到c的都匹配
  ^[a-c] 以abc开头的
  ^[^a-c] 不以abc开头的行
  | 或
  (abc|def)* abc出现o到无穷此 或者 def出现0次或者无穷
  w(abc|def)x 表示wabcx 或者是wbefx 都匹配
  匹配次数
  \{ \}指定前面的表达式出现的次数
  g\(oo\)\{1\}d   =good
  g\(oo\)\{2\}d   =gooood 俩个oo 出现2次
  {2,} >=2
  {2,4} >=2 and /匹配行里以a为结尾的
  正则选项
  -v取反
  -i不分大小写
  -n显示匹配文件的行号
  -c 显示正则表达式匹配的行数
  -q 不显示输出的信息
  去掉前面有空格 和#的 只要有效行
  # grep -v "^$\|^#" /etc/httpd/conf/httpd.conf
  面试的时候肯能出现的匹配
  匹配出make地址HWADDR
  # grep "\(\{2\}:\)\{5\}\{2\}" /etc/sysconfig/network-scripts/ifcfg-eth0
  HWADDR=54:E6:FC:71:17:45
  ip地址
  域名                         www   .baidu   . com
  # grep "\{1,\}\.\{1,\}\.\{2,3\}" ifcfg-eth0 aaawww.baidu.com
  主机名
  url 地址 论坛上贴网址的
  邮箱
  ---------------------------------------------------
  sed交换式的流编辑器
  打印 删除 替换 复制 剪切粘贴导入导出
  处理的时候以行为单位 对文件进行逐行处理
  用法
  sed [ 选项] “动作” 文件名字
  命令 | sed [ 选项] “动作” 文件名字
  打印“p”
  会显示两行 一个是原数据 一个是处理完以后的数据
  sed "p" /etc/passwd有两行
  sed "p;p" /etc/passwd多次动作用;间隔
  sed "p;=" /etc/passwd   = 显示行号
  root:x:0:0:root:/root:/bin/bash   p打印的内容
  1                                  =显示的内容
  root:x:0:0:root:/root:/bin/bash原数据
  bin:x:1:1:bin:/bin:/sbin/nologin
  2
  bin:x:1:1:bin:/bin:/sbin/nologin
  -n 不显示原数据 只显示输出后的结果
  # sed -n "p" /etc/passwd
  打印模几行
  # sed -n "2,5p" /etc/passwd
  # sed -n "1p;3p;5p" /etc/passwd
  ---------------------
  删除 d
  只删除第一行的显示内容
  # sed "1d" /etc/passwd
  # sed "1d;3d" /etc/passwd
  起始行 结果行
  # sed "1,3d" /etc/passwd
  加 -i 选项 是操作原文件(慎用)
  # sed -i "1d" /etc/passwd
  ------------------------------
  用正则表达式来删除 必须要用 / / d 格式匹配
  # sed -n "/xly/,/abc/d" /etc/passwd
  从第 2行开始(包括第2行)在往下删去2行
  # sed "2,+2d" /etc/passwd
  从2开始 删掉第一个是5的倍数行之间的行
  # sed "2,~5d" /etc/passwd
  删除偶数行(能除2的) 每2行删去第1行
  # sed "1~2d" /etc/passwd
  --------------------------------
  替换 s   “ s / / /gi“   g全局   i忽略大小写
  # sed -n "s/a/b/gi" /etc/passwd
  替换多个范围的 1行到3行
  # sed -n "1,3s/a/b/gi" /etc/passwd
  ------
  用正则 修改用// 圈起来
  把所有的数字改成字母
  # sed -n "s//b/g" /etc/passwd
  把包含有字母都删除
  # sed -n "s///g" /etc/passwd
  修改运行级别到3
  # grep initdefault /etc/inittab
  #0 - halt (Do NOT set initdefault to this)
  #6 - reboot (Do NOT set initdefault to this)
  id:5:initdefault:
  # sed "/id/s//3/" /etc/inittab
  #
  在sed 的正则表达式里
  -r
  在正则表达式里 不用转意符 可以用-r 解决
  # sed -r "/id/s/{2}/3/" /etc/inittab
  把/etc/passwd 文件里 没一行的第一个字符删掉
  # sed -n "s/.//" /etc/passwd
  把/etc/passwd 文件里 每一行的第一个和最后一个字符删掉
  () 保存所匹配的字符   & 代替你查找的所有字符
  每一个模式 是\1 \2 ...\9每个模式对应前面的第几个()里的内容
  出现在第一个 是开头 第二个是去掉最后一个的所有内容 的三个是最后一个内容
  # sed -n -r "s/(.)(.*)(.)/\2/" /etc/passwd
  修改ip最后的地址为254
  # sed -r "s/(192.168.1.)(.*)/\1254/" ip.txt
  192.168.1.254
  192.168.1.254
  192.168.1.254
  192.168.1.254
  192.168.1.254
  192.168.1.254
  192.168.1.254
  把一个文件所有的大写 字母加上个小括号
  # sed "s//(&)/g" /etc/passwd
  -----------------------
  添加 a         默认的是每一行都添加一个
  # sed -r "aGATEWAY=192.168.1.254" ifcfg-eth0
  指定位置添加
  # sed -r "1aGATEWAY=192.168.1.254" ifcfg-eth0
  插入 i插入到上面
  # sed -r "1iGATEWAY=192.168.1.254" ifcfg-eth0
  替换 c
  第一行替换成GATEWAY....
  # sed -r "1cGATEWAY=192.168.1.254" ifcfg-eth0
  导入 r
  把有a里的内容 导入到搜索出来1这行的内容的下面
  把只要有1的行导入到a.txt里去
  什么内容到导入到那里原文件
  # sed -r "/1/r a.txt" 1.txt
  导出 w
  把有a的内容写到 1.txt里去 会覆盖之前的内容
  把只要有a的导出到1.txt里
  # sed -r "/a /w 1.txt" a.txt
  ------------
  命令组
  root@xu opt]# sed -n "2=;2p" a.txt
  # sed -n "2{=;p}" a.txt
  -e如果有多个命令要执行的时候 可以加多个 -e 连起来 作成一个命令组
  # sed -n -e "2=" -e "2p" a.txt、
  除了第一行剩下的内容 取反
  # sed -n "1 ! p" 2.txt
  -------------------------
  删出 d
  # sed "d" a.txt
  4n 把当前行 读出下一行 也就是 第4行不读 其他的 都读
  # sed "4n;d" a.txt
  -----------------
  sed 复制
  有俩个空间sed的缓存
  一个是模式空间 里面不存数据
  当sed 处理一个流的时候 他会把他放到 里买 处理的时候拿进来 处理完了拿出去
  二个是保持空间
  默认情况下什么都没有 只有一个换行符\n
  俩个选项
  剪贴
  H 追加导入到保持空间
  h 覆盖导入到保持空间
  # sed "1h;1d;5G" 2.txt
  粘贴
  G 追加粘贴到模式空间
  g 覆盖粘贴到模式空间
  # sed "1H;5G" 2.txt
  # sed "1,3h;5G" 2.txt
  -------------------------------------
  awk单独的一门语言也是逐行处理
  awk 的格式
  awk [选项] “动作” 文件名
  命令 | awk [选项] “动作” 文件名
  awk -F":" '{print FILENAME}'
  位置变量 第一列的值就是$1
  $1 。。。$n 分割
  $0 代表整个行的信息
  位置变量
  # awk -F":" '{print $1,$2}' /etc/passwd
  # head /etc/passwd | awk -F":" '{print $1,$2}'
  打印当前文件名FILENAME
  # awk -F":" '{print FILENAME}' /etc/passwd
  打印分割类的个数 NF
  # awk -F":" '{print NF}' /etc/passwd
  当前处理行的行数 NR
  # awk -F":" '{print NR}' /etc/passwd
  处理当前行在文件内的行数FNR
  # awk -F":" '{print FNR}' /etc/passwd
  AWK的默认分隔符 为空格 和 tab键默认时可以省略 -F
  # head -3 /etc/passwd | awk -F":" '{print $1,$3,$4}'
  root 0 0
  bin 1 1
  daemon 2 2
  -------------
  awk 处理数据的时候顺序是三个   行前 行中 行后
  行前
  BEGIN{}
  # awk -F":" 'BEGIN{print NR}' /etc/passwd
  0
  行中
  {}
  # awk -F":" '{print NR}' /etc/passwd
  行后的
  END{}
  # awk -F":" 'END{print NR}' /etc/passwd
  73
  -------------------
  用正则
  awk '条件{print NR}'
  ~ 匹配
  !~ 不匹配
  匹配是root的
  # awk -F ":" '$1~/root/{print $1}' /etc/passwd
  root
  比较符号
  ===   !=> >=<
页: [1]
查看完整版本: shell中的数组、正则表达式、sed、awk的使用