• Shell及Linux三剑客grep、sed、awk


    shell 壳
    操作系统与应用程序之间的一个命令翻译工具
    sh  bash zsh
    一、常用命令
    用--help 
    (1)head 默认获取文件前10行   ,前三行用 head -3   前几个字节,用head -c 3 前三个字节
    more是分页的,cat不分页
    (2)tail 默认获取文件后 10行,   tail -3  尾部三行
    获取中间某几行的命令,获取5-8行的数据,可以使用 head -8 文件名 | tail -3 
    (3)cut 分割, 提取文件指定的列  -d  ,获取第一列和第三列,以冒号分隔。 cut -d“:“ -f1,3 文件名  结果展示例如 root:admin。默认以tab键进行分割(不支持不规律的空格)  -d 指定分割符 -f指定获取的列号。
    (4)uniq 去重 要和sort 联合使用

    去掉重复的内容,选项, -d 仅打印有重复的元素(duplicate) -c打印元素重复的个数,

    管道符的情况下,后面的命令不需要 加上文件名,使用这个去重的时候,先要排序,然后再去重,如果不排序,只能去重两个相邻的是否重复,所以要和sort 联合使用。sort -r 文件名 |  uniq -d    。 sort -r 文件名 | uniq -c   打印重复元素的个数。

    head -50 test.log | cut -d" " f4 | sort | uniq -c  打印出前50行里去重的用户名和个数

    head  -50 test.log | cut -d" " f4 | sort | uniq  ,获取前50行日志里的用户名
    (5)sort     排序默认以ASCII码数值从小到大排序。  选项 -n 以数值大小排序  -r倒序   -t 指定分隔符,默认为空格。 -knum指定以某个字段来排序

    sort -r test.txt 
    (6)wc (word count)

    计算文本数量

    选项 wc-l打印行数

    wc -w打印单词数

    wc -c打印字节数

    wc -L打印最长字节数


    二、变量
    分类
    定义变量

    1、本地变量

    username="tester01"等号两侧不能有空格

    打印这个变量,echo $username

    可以用一个命令作为变量的值

    one_var=$(ls /)

    echo $one_var


    2、全局变量

    export user="tester02" 直接声明一个全局变量


    3、内置变量

    env查看所有的环境变量

    $0获取当前执行的shell脚本文件名、包括脚本路径

    $n 获取当前执行的shell脚本的第n个参数值,n=1.....9,如果n>9就要用大括号括起来{10}

    $# 获取当前shell命令行中参数的总个数

    $?获取执行上一个指令的返回值(0为成功,非0为失败)

    4、查看变量

    echo $user  或者 echo "$user" ,但是echo '$user'是不行的,单引号展示的是所见即所得

    echo "${user}"  最常用

    在shell脚本中不能使用 echo $user ,在脚本中 必须使用echo "${user}"

    三、数值运算
    1、支持的运算

    + - * / %  < <= > >=   =  !=

    2、方式一

    echo $((1 + 1)) 用两个(())

    $(算数表达式)

    变量可以不加$

    one_number=10

    two_number=20

    echo $((one_number + two_number))

    建议使用 这种方式

    3、方式二

    expr 算数表达式 

    echo "$(expr 20 \* 10)"  ,这个* 需要转义

    四、条件表达式
    1、返回值

    条件成立,返回0

    条件不成立,返回1

    2、逻辑表达式

    && 和 || 

    如果前面的成立了,才会执行后面的

    [ 1== 1 ] && echo "success"  如果1==1成立了,就会执行后面的

    [ 1==1 ] || echo "success" 如果1==1成立了,就不会执行后面的

    [ "${user}" == "tester" ] && echo "yes" || echo "no" 如果成立 执行 echo “yes”,否则执行echo “no”


    3、文件表达式

    -f 判断输入内容是否是一个文件

    -d判断输入内容是否是一个目录

    -x 判断内容是否可执行

    -e判断文件是否存在


    4、数值操作符

    -eq  相等

    -gt  大于

    -lt 小于

    -ne  不等于


    5、字符串比较

    str1 == str2 str1和str2字符串内容一致

    str1 != str2  str1和str2 字符串内容不一致,!表示相反的意思

    五、shell脚本格式
    1、格式要求

    在文件首行指定执行shell的程序以及相关说明

    #!/bin/bash

    #Author:testor

    #Date:2022-01-01

    shell脚本文件后缀,建议命令为.sh

    脚本执行失败时,使用exit返回非零值,来退出程序

    默认缩进4个空格

    shell脚本的命令简单、有意义


    注释

    单行注释

    #

    六、函数

    1、格式

    bash 文件名.sh

    格式一:

    函数名()

    {

            命令1

            命令2

    }

    格式二:

    function test

    {

            命令1

            命令2

    }
    test(){
        echo "Hello ,${LOHNAME}, today is ${date}"
    }
    2、参数

    函数体调用参数

            函数名(){

                    函数体 $n

            }

    调用函数给函数传参数

            函数名  参数


    调用变量

    1. #!/bin/bash
    2. #Author:tester
    3. #Date: 2022-1-18
    4. #command line parameter
    5. #$REPLY
    6. read -p "请输入你的姓名:" name
    7. read -p "请输入你的年龄:" age
    8. function info
    9. {
    10. echo -e "你的姓名为: ${name}\n你的年龄为: ${age}"
    11. }

    如何接收命令行传过来的参数

    1. #!/bin/bash
    2. 传参
    3. echo  "第一个参数为: $1"
    4. echo  "第二个参数为:$2"
    5. ${10}  大于10个参数时候,这么写
    6. echo  "shell脚本名字为:$0"
    7. echo  "shell脚本的参数个数为:$#"
    8. echo  "shell脚本的所有参数: $*"
    1. #!/bin/bash
    2. function test
    3. {
    4.     echo -e “您当前的名字:$1\n你的年龄是:$2
    5. }
    6. test"土豆" "地瓜"

    第一个实参会被$1接收,第二个实参会被$2接收

    1. #!/bin/bash
    2. read -p "请输入您的姓名:" name
    3. read -p "请输入您的年龄:" age
    4. function test
    5. {
    6. ehco -e "你的姓名为:$1\n你的年龄为:$2"
    7. }
    8. test "${name}" "${age}"

    脚本中如何接收命令行参数

    1. #!/bin/bash
    2. function test
    3. {
    4. echo -e "您的姓名为:$1\n您的年龄为:$2"
    5. }
    6. test $1 $2

    bash function_params.sh "姓名" 18

    3、input,提示用户从键盘中输入

    read 

    read value

    read -p prompt value

    七、流程控制

    1、if

    if [ 条件1 ]

    then

             指令1

    elif[ 条件2 ]

    then 

            指令2

    else 

            指令3

    fi

    条件表达式0 为真,非0为假,如果不使用命令行接收,用${REPLY}这个变量进行接收

    -gt 大于70

    1. #!/bin/bash
    2. read -p "请输入你的年龄:"
    3. if[ "${REPLY}" -gt 70 ]
    4. then
    5. echo "如果大于70了,就要锻炼"
    6. elif[ "${REPLY}" -gt 18 ]
    7. then
    8. echo "恭喜你"
    9. else
    10. echo "小于18的,该干啥干啥"
    11. fi

    2、for

    格式一:

    for 值 in 列表

    do 

            执行语句

    done

    ls / 展示跟目录下的列表作为一个变量,赋值给dir

    1. #!/bin/bash
    2. dir=$(ls /)
    3. index=1
    4. for i in ${dir}
    5. do
    6. echo "第${index}个文件为: ${i}"
    7. index=$((index+1))
    8. done

    调试shell 脚本使用 bash -x 脚本名.sh

    格式二:

    max=10

    for ((i=1;i<=max;i++))

    do

            echo "$i"

    done

    1. #!/bin/bash
    2. max=10
    3. for((i=1;i
    4. do
    5. echo"${i}"
    6. done

    3、while

    只要条件满足,就一直循环

    while 条件

    do

             执行语句

    done 

    1. #!/bin/bash
    2. #Author:
    3. #Date:2022-01-01
    4. read -p "请输入一个数字:"a
    5. while [ "${a}" -lt 20 ]
    6. do
    7. echo "${a}"
    8. a=$((a+1))
    9. done

    4、until

    只要条件不满足,就一直循环

    until 条件

    do         

            执行语句

    done

    5、case

    case 变量名 in

            值1)

                    指令1

                            ;;

            值2)

                    指令2

                            ;;

            值3)

                    指令3

                            ;;

            *)        

                    指令4

                            ;;

    esac

    1. #!/bin/bash
    2. case $2 in
    3. +)
    4. echo "$1 + $3= $(($1+$3))"
    5. ;;
    6. -)
    7. echo "$1 - $3= $(($1-$3))"
    8. ;;
    9. \*)
    10. echo "$1 / $3= $(($1/$3))"
    11. ;;
    12. /)
    13. echo "$2 can not calcaulate"
    14. ;;
    15. esac

    bash  test.sh 10 \* 5  

    10*5=50

    八、文本处理三剑客

    1、grep

    两种形式

    grep 

    选项    含义

    -i         忽略大小写

    -c        只输出匹配行的数量

    -n        显示行号

    -r         递归搜索

    -E        支持拓展正则表达式

    -w        匹配整个单词

    -l           只列出匹配的文件名

    -F          不支持正则,按字符串字面意思进行匹配

    例如 grep “$USER” /etc/passwd && echo "$USER existed" || echo "$USER not existed"

    2、sed

    sed  stream editor 流编辑器,sed把处理的内容(文件),直到文件末尾。

    sed 功能

    s  替换 substitute sub

    p  显示 print 

    d  删除 delete

    cai 增加c/a/i

    sed命令执行过程

    sed -n ‘3p’ test.txt 

    sed核心应用

    1)sed 查找p

    查找格式

    ‘1p’ ‘2p’   指定行号进行查找

    ‘1,5p’     指定行号范围查找

    '/lidao/p'   类似于grep ,过滤

    ‘/10:00,/11:00/p’  表示范围的过滤

    sed -n  '4, $p' test.txt  表示第4行到最后一行 

    wc -l  access.log 看有多少行

    sed -n  '/11:02:30/p' access.log  表示范围的过滤

    sed -n '/11:02:29/,/11:02:30/p' access.log | wc -l  查看从11:02:29这秒,到11:02:30这秒的数据总共有多少行。

    如果结尾的点不正确,会一致显示到文件最后一行数据。

    2)sed -删除

    sed '3d' test.txt  删除第3行

    sed '2,3d' test.txt   删除2-3行

    sed '/li/d'  test.txt  删除文件中的匹配到li的行

    删除文件中的空行和包含井号的行

     sed -r '/^$|#/!d'  遇到空行或井号的不删除

     sed -nr '/^$|#/!p'  遇到空行或井号的不显示行号

    3)sed - 增加cai

    命令

    c  replace 替代这行的内容

    a   append 追加,向指定行的下一行或每一行追加内容

    i   insert插入,向指定的行上一行或每一行插入内容()

    sed '3a 33,lidao996,uf' test.txt  在第3行的下一行追加一行

    sed '3i 44,dd,rr' test.txt 在第3行的上一行插入一行内容 

    sed '3c 44,55,77' test.txt  把第3行的内容替换

    向文件中追加多行内容

    sed '$a sdf \nsdasd \n'  向最后一行追加sdf  sdasd

    4)sed -替换s   substitute替换

    g 全局替换,加上g后,代表全局替换每行所有匹配的内容

    sed 's#[-0-9]##g' test.txt

    sed默认只替换每行第一个匹配的内容

    sed 's#[0-9]##' test.txt 

    sed 后向引用也叫反向引用

    口诀,先保护,再引用

    替换格式

    s###g

    s///g

    s@@@g

    echo 123456 | sed -r 's#(.*)#<\1>#g'

    <123456>

    反过来顺序

     echo old_test | sed -r 's#(^.*)_(.*$)#\2_\1#g'

    test_old

    3、awk

    awk一门语言,类似于c语言,过滤统计,计算有关的,过滤,统计日志。

    行与列

    名词        awk中叫法        说明

    行            记录record        每一行默认通过回车分割的

    列           字段,域field     每一列默认通过空格分割的

    awk中行和列结束标记都是可以改的

    awk 内置变量

    1)取行:

    NR==1 , 取出某一行

    NR>=1 && NR<=5 ,取出1到5行范围  

    awk 'NR==1' test.txt

    符号 > < >= <=  == !=

    2)取列

    -F  制定分隔符,制定每一列结束标记(默认是空格 tab键)

    $数字,取出某一列, 例如 awk ‘{print $5}’,在awk中$内容,表示取出某一列。

    $0 整行的内容,

    {print}

    NF    Number of Field 每行有多少列, $NF表示最后一列。

    awk -F: '{print $1, $NF}' /test.txt | column -t 

    使用awk调换passwd 第1列和最后一列内容,然后显示每一行内容(调换后的)

    awk -F: '{print $NF, $2, $3,$4,$5, $6,$1}' /etc/passwd

    FS -F: === -v FS=:

    OFS 

    九、日志分析系统演练

     1、统计每位测试人员执行用例的总数

    2、分别统计每位测试人员执行用例成功和失败的总数

    3、将1、2合并,同时分别统计每位测试人员执行用例CRITICAL、ERROR日志等级数以及所有测试人员每项总数

    4、使用shell脚本来实现,并显示菜单,选择不同的选项则打印不同的内容

  • 相关阅读:
    Java面试题之CAS和ABA问题
    Markdown语法之数学公式【总结】
    网络编程——python
    【ES6】
    Vector容器(黑马程序员)
    VEGAS Pro 20发布-剪辑师们,是时候更换了吗?
    Prometheus 简介
    网页自动化截图接口推送到手机(截图维格表数据)
    Flutter 3.3 正式发布啦
    HDFS基本操作命令
  • 原文地址:https://blog.csdn.net/qq_30353203/article/details/122353386