egrep 及 bash 中的环境变量

回顾: shell 的基础特性、grep

    shell:
        #!/bin/bash

        过程式:以指令为中心
        对象式:以数据为中心

    grep:文本过滤器,global search regular expression and print out the line
        PATTERN

        REGEXP:
            1. BRE: basic regualr expression
            2. ERE: extended regular expression

        BRE:
            1. 字符匹配:., [], [^]
            2. 次数匹配: \?, \+, *, \{m\}, \{m,n\}
            3. 位置锚定: ^, $, \<, \b, \>, \b
            4. 分组:  \(\)
                    后向引用: \1, \2, ...

    vim, sed, awk, nginx 当涉及到文本时,都能使用到正则表达式

egrep 及扩展的正则表达式

    egrep = grep -E

    egrep [OPTIONS] PATTERN [FILE...]

    扩展正则表达式的元字符:
        1. 字符匹配:

            .
            []
            [^]

        2. 次数匹配

            ?
            +
            *
            {m}
            {m,n}

        3. 位置锚定

            ^
            $
            \<, \b
            \>, \b

        4. 分组

            ()
            后向引用: \1, \2, ...

        5. 或者

            a|b
                C|cat: 表示的意思是,C 或者 cat
                (C|c)at: 如果想要对单个字符做【或者】,使用分组括起来

    basename: 基名
    dirnaem: 目录名
        /usr/lib/java 的基名是 java, 目录名是 /usr/lib


    练习:
        1. 显示当前系统 root、 centos 或 user1 用户的默认 shell 和 UID。

            grep -E "^(root|centos|user1)\>" /etc/passwd | cut -d: -f1,3,7

        2. 找出 /etc/rc.d/init.d/functions 文件(centos6)中某单词后面跟一个小括号的行。

            grep -E -o "^[_[:alnum:]]+\(\)" /etc/rc.d/init.d/functions

            注释: 加 -o 与不加 -o 的区别是,
                1. 不加,后面会继续匹配出小括号后面的内容,比如 methodName() {
                2. 加上,只匹配出了方法名,比如:methodName()

        3. 使用 echo 输出一个绝对路径,使用 egrep 取出其基名。

            echo "/usr/lib/java" | grep -E -o "[^/]+$"

            改进

            echo "/usr/lib/java/" | grep -E -o "[^/]+/?$" | cut -d/ -f1

            说明:
                基名是以除了分隔符 【/】 之外的任意字符结尾的任意字符
                -o: 只匹配正则表达式匹配到的内容

                基名后面可能会出现 【/】 分隔符,所以使用 /?,表示分隔符 【/】 可能会出现一次或零次


        4. 使用 echo 输出一个绝对路径,使用 egrep 取出其目录名,类似于 dirname 命令的结果。




        4. 找出 ifconfig 命令结果中 1-255 之间的数值。

        5. 找出 ifconfig 命令结果中的 IP 地址。

fgrep: 不支持正则表达式搜索



bash 的基础特性(4)

    变量类型:
        数据存储格式、存储空间大小、参与运算种类

    字符型
    数值型:
        整型
        浮点型

    强类型:定义变量时必须指定类型、参与运算必须符合类型要求
    弱类型:无需指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无需事先定义可直接调用
        bash

    bash 中的类型的种类:
        根据变量的生效范围等标准:
            1. 本地变量:生效范围为当前 shell 进程,对当前 shell 之外的其它 shell 进程,包括当前 shell 的子 shell 进程均无效
            2. 环境变量:生效范围为当前 shell 进程及其子进程
            3. 局部变量:生效范围为当前 shell 进程中某代码片段(通常指函数)
            4. 位置变量:$1, $2, ...来表示,在脚本代码中调用命令行传递进来的参数
            5. 特殊变量:$?, $0(指命令本身), $*, $@, $#

        1. 本地变量:
            变量赋值:name='value'
                可以使用引用:
                    value:
                        (1) 可以是直接字符串;name="username"
                        (2) 变量引用: name="$username"
                        (3) 命令引用: name=`COMMAND`, name=$(COMMAND)
            变量引用:${name}, $name
                "": 弱引用,其中的变量引用会被替换为变量值
                '': 强引用,其中的变量引用不会被替换为变量值
            显示已定义的所有变量
                set
            销毁变量:
                unset name
        2. 环境变量:
            变量声明、赋值:
                export name=VALUE
                declare -x name=VALUE
            变量引用:$name, ${name}
            显示所有环境变量:
                export
                env
                printenv
            销毁:
                unset name

            bash 有许多内建的环境变量:
                PATH, SHELL, UID, HISTFILE, HISTSIZE, HOME, PWD, OLDPWD, PS1


        只读变量:
            readonly name
            declare -r name

        3. 位置变量:
            在脚本代码中调用命令行参数
                $1, $2, ...: 对应调用第1、第2等参数
                $0: 命令本身

                $*: 传递给脚本的所有参数
                $@: 传递给脚本的所有参数

                    区别:$*: 把所有参数当做一个字符串
                         $@: 把每个参数当做一个字符串

                $#: 传递给脚本的参数的个数

            示例:判断给出的文件的行数

                #!/bin/bash
                linecount=$(wc -l $1 | cut -d" " -f1)
                echo $linecount

bash 的配置文件:

    按生效范围划分,存在两类:
        全局配置:
            /etc/profile
                /etc/profile.d/*.sh
            /etc/bashrc
        个人配置:
            ~/.bash_profile
            ~/.bashrc

    按功能划分,存在两类:
        profile类:为交互式登录的 shell 提供配置
            全局: /etc/profile, /etc/profile.d/*.sh
            个人: ~/.bash_profile
            功用:
                (1) 用户定义环境变量
                (2) 运行命令或脚本

        bashrc类:为非交互式登录的 shell 提供配置
            全局: /etc/bashrc
            个人: /.bashrc
            功用:
                (1) 用于定义别名
                (2) 用于定义本地变量


    shell 登录:
        交互式登录:
            直接通过终端输入账号密码登录
            su - Username 或 su -l Username 切换的用户

            读取配置文件次序:
                1. /etc/profile
                2. /etc/profile.d/*.sh
                3. ~/.bash_profile
                4. ~/.bashrc
                5. /etc/bashrc
        非交互式登录:
            su Username
            图形界面下打开的终端
            执行脚本

            读取配置文件次序:
                1. ~/.bashrc
                2. /etc/bashrc
                3. /etc/profile.d/*.sh

    问题:
        1. 定义对所有用户都生效的别名
            /etc/bashrc
            例如: 自定义用户登录提示信息:/etc/profile.d/*.sh

        2. 让用户的 PATH 环境变量的值多出一个路径,例如 /usr/local/apache2/bin

            export PATH="$PATH:/usr/local/apache2/bin"

            管理员? 定义在 ~/.bash_profile 中
            所有? 定义在 /etc/profile.d/*.sh 中

bash 中的算数运算,可以查看 help let
    +, -, *, /, %, **


    实现算术运算:
        1. let var=算术表达式
        2. var=$[算术表达式]
        3. var=$((算术表达式))
        4. var=$(expr arg1 arg2 arg3 ...)

        乘法符号在 $(expr) 中需要转义

        bash 有内建的随机数生成器 $RANDOM

        例子:生成 1-60之间的随机数

            echo $[$RANDOM % 60 + 1]
    增强型赋值:
        +=, -=, *=, /=, %=

        例如:let count+=1

    自增,自减
        let var+=1
            let var++

        let var-=1
            let var--

    
    说明:
        $( )与``:命令替换
        ${ }:变量替换

    练习:
        1. 写一个脚本,计算 /etc/passwd 文件中第10个用户和第20个用户的ID之和
            #!/bin/bash
            num1=$(head -10 /etc/passwd | cut -d: -f3)
            num2=$(head -20 /etc/passwd | cut -d: -f3)
            echo $[$num1+$num2]


        2. 写一个脚本,传递两个文件路径为参数给脚本,计算这两个文件中所有空白行之和
            #!/bin/bash
            num1=$(grep "^[[:speace:]]*$" $1 | wc -l)
            num2=$(grep "^[[:speace:]]*$" $2 | wc -l)
            echo $[$num1+$num2]

        3. 统计 /etc/, /var, /usr 目录共有多少个一级子目录和文件

条件测试:
    判断某需求是否满足,需要由测试机制来实现:

        注意:专用的测试表达式需要由测试命令辅助完成测试过程

    测试命令:
        test EXPRESSION
        [ EXPRESSION ]
        [[ EXPRESSION ]]

        注意: EXPRESSION 前后必须有空白字符

    bash的测试类型:
        数值测试:
            -gt, -ge, -eq, -ne, -lt, -le

            例子: test 1 -gt 3;echo $?

        字符串测试:
            ==, >, <, !=
            =~: 左侧的字符串是否能被右侧的 PATTERN 所匹配到
                注意:此表达式一般用于 [[  ]] 中

            -z "String": 测试字符串是否为空
            -n "String":测试字符串是否不为空

            注意:用于字符串比较时用到的操作数都应该使用引号

            例子:     name=Obama
                    [[ "$name" =~ ^O.* ]]
                    判断 $name 是否以首字母O开头


        文件测试:

bash 自定义退出状态码
    exit [n]: 自定义退出状态码
        注意:脚本中一旦遇到 exit 命令,脚本会立即终止,终止退出状态取决于 exit 命令后面的数字
              如果未给脚本指定退出状态码,整个脚本的退出状态取决于脚本中执行的最后一条命令的状态码
    练习:
        1. 写一个脚本,接受一个文件路径为参数
            如果参数的个数小于1,则提示用户“至少应该给一个参数”,并立即退出
            如果参数的个数不小于1,则显示第一个参数所指向的文件中的空白行数


            #!/bin/bash
            test ?# -lt 1 && echo "至少应该给一个参数" && exit 1 || echo $(grep "^[[:space:]]*$" $1 | wc -l)

            // 考察点在于怎么判断参数个数是否小于1,注意数值比较用转移符号,千万不要使用 <, > 因为这是字符串比较


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353