zoukankan      html  css  js  c++  java
  • Linux的系统符号与正则表达式

    1 Linux系统符号

    在Linux中,符号都有一些各自的含义和作用,并且可以跟一些命令进行组合使用。

    1.1 通配符符号

    在Linux有两种通配符符号,分别是 *{ }

    {} 符号:可以用来生成序列。比如:

    # 生成序列
    [root@web syushin]# echo {a..e}
    a b c d e
    [root@web syushin]# echo {A..E}
    A B C D E
    [root@web syushin]# echo {1..5}
    1 2 3 4 5
    
    # 指定间隔序列,{开始..结束..间隔}
    [root@web syushin]# echo {1..10..2}
    1 3 5 7 9
    

    常见的用法:批量创建文件和备份单个文件

    [root@web syushin]# touch {a..d}.txt
    [root@web syushin]# ls
    a.txt  b.txt  c.txt  d.txt
    
    # 备份一个文件
    [root@web syushin]# cp a.txt{,.bak}
    [root@web syushin]# ls
    a.txt  a.txt.bak
    

    * 符号:在日常运维中非常常用,在文件扩展名上,它用来表示任意一个字符,

    [root@web syushin]# ls
    abc  adc  aec
    [root@web syushin]# ls a*c
    abc  adc  aec
    

    在运算时,它表示乘法:

    [root@web syushin]# let "a=2*3"
    [root@web syushin]# echo $a
    6
    # 运算时两个 ** 表示乘方
    [root@web syushin]# let "b=2**2"
    [root@web syushin]# echo $b
    4
    

    1.2 引号符号

    • 单引号 '':所见即所得,单引号会去掉引号里面字符串的特殊含义,字符串是什么就是输出什么

    • 双引号 "":双引号与单引号作用类型,但是会解析特殊字符串,包括 ', $, 等,如果要忽略特殊字符,就可以用 来转义。

    • 反引号 `` :跟 $() 一样,一般是把命令放到反引号里面,反引号里面的命令会先被执行,得到的结果会返回给反引号外面的命令执行

    1.3 定向符号

    定向符号包括如下几种:

    定向符号 说明
    > 标准输出重定向符号
    >> 标准输出追加重定向符号
    < 标准输入重定向符号
    << 标准输入追加重定向符号
    # > 标准输出重定向,先清空文件内容,再添加数据信息
    $ echo "hello" > a.txt
    
    # >> 在文件末尾追加信息,不会删除文件原有信息
    $ echo "hello2" >> a.txt
    
    # < 标准输入,从文件获取输入
    $ xargs < a.txt
    

    在Linux中,一切都是文件,每个命令运行时都会打开三个文件:

    • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
    • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
    • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

    参考:Shell 输入/输出重定向--菜鸟教程

    举例来说:标准输入重定向:> 等价于 1>, 标准输入追加重定向:>> 等于 1>>

    $ echo "hello" > a.txt 
    $ cat a.txt 
    hello
    $ echo "hello" 1> b.txt
    $ cat b.txt 
    hello
    

    标错错误输入重定向就可以写为:2> ,标准错误追加重定向就是: 2>>

    $ ech "test" 2> a.txt
    $ cat a.txt 
    -bash: ech: 未找到命令
    $ ech "test" 2>> a.txt
    $ cat a.txt 
    -bash: ech: 未找到命令
    -bash: ech: 未找到命令
    

    如果希望将标准输出输入都重定向到一个文件中,可以这样写:

    $ echo "hello" &>> a.txt 
    $ ech "hello" &>> a.txt 
    $ cat a.txt 
    hello
    -bash: ech: 未找到命令
    
    # 也可以使用 2>&1
    $ echo "bbb" >> b.txt 2>&1
    $ ech "bbb" >> b.txt 2>&1
    $ cat b.txt 
    bbb
    -bash: ech: 未找到命令
    

    1.4 路径相关符号

    • . :表示当前路径
    • .. :表示上一级目录信息
    • - : cd命令中,- 表示上一次所在目录信息,实际上等价于 $OLDPWD 变量的值
    • ~ : 用户的家目录,root用户是 /root,普通用户默认是 /home/用户名

    1.5 逻辑符号

    Linux命令行中的逻辑符号跟一些编程语言的逻辑运算符一样,一旦确定逻辑表达式的真假,表达式后面的判断条件就不会执行。命令行中常用两个符号:

    • && :表示并且,示例:command1 && command2,只有command1执行成功时,command2才执行

    • || :表示或者,示例:command1 || command2,只有当command1执行失败时,command2才执行

    除此之外,命令行还常见下面的写法:

    # 不管前面命令有没有执行成功,后面的命令继续执行
    command1 ; command2 ; command3
    

    2 正则表达式

    正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。

    在Linux中,正则表达式分为普通字符和元字符两种字符。

    • 普通字符:就是一个简简单单的字符串,没有特殊含义;
    • 元字符:有特殊意义的字符,可以被 grepsedawk 等命令工具所解析。

    在Linux中,常用的正则表达式有:

    • POSIX 基本正则表达式(BRE)引擎
    • POSIX 扩展正则表达式(BRE)引擎

    2.1 基本正则表达式

    所有支持正则表达式的工具都兼容基本正则表达式,常见的基本正则表达式如下:

    正则表达式 说明
    普通字符 匹配普通字符本身
    . 匹配任意一个字符
    * 匹配前面一个字符出现0次或者多次
    ^ 匹配字符串的开头,如 ^a 表示匹配以字母a开头的
    $ 匹配字符串的结尾,如 a$ 表示匹配以字母a结尾的
    [] 匹配字符集合中包含的任意一个字符
    [^] 取反,匹配不在字符集合中的字符
    [x-y] 匹配指定字符范围内的字符
    转义字符,将有特殊含义的字符去掉其含义

    示例:以grep命令和下面文件为例

    [root@web syushin]# cat a.txt 
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    1 gogle 
    2 goggle
    3 google 
    123456
    
    abcedf
    

    匹配以root开头的行:

    [root@web syushin]# grep '^root' a.txt 
    root:x:0:0:root:/root:/bin/bash
    

    匹配以bash结尾的行:

    [root@web syushin]# grep 'bash$' a.txt 
    root:x:0:0:root:/root:/bin/bash
    

    匹配空行:

    [root@web syushin]# grep '^$' a.txt 
    
    [root@web syushin]# 
    

    匹配任意一个字符在go和gle中间的行:

    [root@web syushin]# grep 'go.gle' a.txt 
    2 goggle
    3 google 
    

    匹配 go和gle 中间有任意多个字符的行:

    [root@web syushin]# grep 'go.*gle' a.txt 
    1 gogle 
    2 goggle
    3 google
    

    匹配以数字开头的行:

    [root@web syushin]# grep '^[0-9]' a.txt 
    1 gogle 
    2 goggle
    3 google 
    123456
    

    匹配第一个字符是数字1到2,第二个字符是空格的行:

    [root@web syushin]# grep '[1-2] ' a.txt 
    1 gogle 
    2 goggle
    

    匹配不是以字母开头的行:

    [root@web syushin]# grep '^[^a-z]' a.txt 
    1 gogle 
    2 goggle
    3 google 
    123456
    

    2.2 扩展正则表达式

    扩展正则表达式仅在部分程序中支持,比如 egrepgrep -Eawksed -r等。

    正则表达式 说明
    `x y`
    x? 匹配0个或者1个前面的字符x
    x+ 匹配至少1个字符x
    x{m} 匹配前一个字符x出现连续m次
    x{m,} 匹配前一个字符x至少出现m次
    x{m,n} 匹配前一个字符x至少出现m次,最多出现n次
    (xxx) 将匹配的信息作为一个整体进行查询

    示例:匹配至少包含1个数字1或者多个数字1的行:

    [root@web syushin]# egrep '1+' a.txt 
    bin:x:1:1:bin:/bin:/sbin/nologin
    1 gogle 
    123456
    

    匹配至少包含2个字母o的行:

    [root@web syushin]# egrep 'o{2,}' a.txt 
    root:x:0:0:root:/root:/bin/bash
    3 google
    

    匹配包含google或者goggle的行:

    [root@web syushin]# egrep 'go(o|g)gle' a.txt 
    2 goggle
    3 google
    

    3 常见应用

    3.1 获取网卡的IP地址

    [root@web syushin]# ip a s ens33
    2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:0c:29:00:97:2e brd ff:ff:ff:ff:ff:ff
        inet 192.168.18.150/24 brd 192.168.18.255 scope global noprefixroute ens33
           valid_lft forever preferred_lft forever
        inet6 fe80::9e44:d201:cf43:83c5/64 scope link noprefixroute 
           valid_lft forever preferred_lft forever
    

    方法一:sed方法

    # 先过滤出ip地址所在行
    [root@web syushin]# ip a s ens33| sed -n '3p'
        inet 192.168.18.150/24 brd 192.168.18.255 scope global noprefixroute ens33
    
    # 将ip地址前面的部分替换为空
    [root@web syushin]# ip a s ens33| sed -n '3p' | sed 's#.*et ##g'
    192.168.18.150/24 brd 192.168.18.255 scope global noprefixroute ens33
    
    # 然后将ip地址后面的替换为空,得到ip地址
    [root@web syushin]# ip a s ens33| sed -n '3p' | sed 's#.*et ##g' | sed 's#/24.*##g'
    192.168.18.150
    
    # 优化写法1:
    [root@web syushin]# ip a s ens33| sed -n '3p' | sed -r 's#^.*et |/24.*##g'
    192.168.18.150
    
    # 优化写法2:使用括号在sed的后项引用前项写法
    [root@web syushin]# ip a s ens33| sed -n '3p' | sed -r 's#^.*et (.*)/24.*#1#g'
    192.168.18.150
    

    方法二:awk

    [root@web syushin]# ip a s ens33 
    2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:0c:29:00:97:2e brd ff:ff:ff:ff:ff:ff
        inet 192.168.18.150/24 brd 192.168.18.255 scope global noprefixroute ens33
           valid_lft forever preferred_lft forever
        inet6 fe80::9e44:d201:cf43:83c5/64 scope link noprefixroute 
           valid_lft forever preferred_lft forever
    # 获取指定行
    [root@web syushin]# ip a s ens33  | awk 'NR==3'
        inet 192.168.18.150/24 brd 192.168.18.255 scope global noprefixroute ens33
    
    # 获取指定行的第2列
    [root@web syushin]# ip a s ens33  | awk 'NR==3{print $2}'
    192.168.18.150/24
    
    # 指定/为分隔符,获取第1列得到IP地址
    [root@web syushin]# ip a s ens33  | awk 'NR==3{print $2}'|awk -F'/' '{print $1}'
    192.168.18.150
    
    # awk支持指定多个分隔符,优化写法:
    [root@web syushin]# ip a s ens33  | awk 'NR==3' | awk -F '[ /]' '{print $6}'
    192.168.18.150
    

    方法3:使用hostname命令

    [root@web syushin]# hostname -I
    192.168.18.150
    

    4 参考教程

  • 相关阅读:
    wireshark 实用过滤表达式(针对ip、协议、端口、长度和内容)
    32:从1到n整数中1出现的次数
    31:连续子数组的最大和
    30:最小的K个数
    29:数组中出现次数超过一半的数字
    28:字符串的排列
    27:二叉搜索树与双向链表
    26:复杂链表的复制
    25:二叉树中和为某一个定值的路径
    24:二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/syushin/p/14511469.html
Copyright © 2011-2022 走看看