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 参考教程

posted @ 2021-03-10 14:30  syushin  阅读(405)  评论(0编辑  收藏  举报