正则表达式
基础
语法汇总:
| ^word | 以word为行首的那一行 |
|---|---|
| word$ | 以word为行尾的那一行 |
| . | 代表一个任意字符 |
| * | 代表前面的字符重复0次或多次,注意可以是0次 |
| \ | 转义 |
| [多个字符] | 代表多个字符中的一个,或的关系 |
| [a-z] | -代表返回,比如a-z表示全部小写字母,A-Z代表所有大写字母。 |
| [^字符] | 取反,不包含这个字符。注意^在[]里和[]外的不同含义 |
\{n,m\} |
{}里加次数,表示重复指定次数。\{n,m\}是重复n到m次。\{n,\}是重复n次以上 |
另外,注意区分正则表达式和通配符的区别。强调*这个字符
在正则中表示重复前面的字符0次或多次
在通配符中表示任意字符
举例来说。(ls命令是不支持正则的,grep,sed支持)
1 | ls -l a* |
是取出以a开头的所有文件
1 | grep 'a*' 某文件 |
会把文件中所有的数据全部取出,因为正则中*可以表示0次,所以a*的含义就是所有字符,而不是以a开头的意思
正则表达式延申
上面是正则的基本语法,除此之外,正则还有延申的特殊参数
要使用的话用grep -E,不过更常用的是egrep
| + | 代表前面的字符重复1次或多次,注意和*的区别 |
|---|---|
| ? | 0次或1次 |
| | | 或的含义 |
| () | 分组 |
| ()+ | 多个重复分组 |
sed
sed当管道使用
sed是一个管道命令。
sed后接动作要用单引号括住
1 | sed '2,5d' |
2,5表示对第二行到第五行进行动作。d表示删除动作
可以接的动作如下
d删除。前面加上行号。如上所示,如果要实现从某一行删除到文件结束
sed '2,$d'a 新增。后面加上内容。在当前行的下一行新增内容
1
2
3
4
5[api@kfxqtyglpt ~]$ cat test.txt
456
[api@kfxqtyglpt ~]$ cat test.txt | sed '1a okokok'
456
okokoksed也是管道操作,所以直接输出到了控制台上
i在前面新增。接的内容插入在上一行
1
2
3[api@kfxqtyglpt ~]$ cat test.txt | sed '1i helphelp'
helphelp
456p 显示
我们要显示一个文件的第10到20行,可以用
1
head -n 20 | tail -n 10
现在有了sed,可以直接
1
sed -n '10,20p'
s 搜索并替换,这是sed很常用的功能
1
sed 's/old/new/g'
old部分可以用正则表达式
c按行取代
1
2
3
4
5
6[api@kfxqtyglpt ~]$ cat test.txt
456
the last line
[api@kfxqtyglpt ~]$ cat test.txt | sed '1c the first line'
the first line
the last line
sed直接修改文件
比较危险,使用时先用管道场景进行测试
1 | sed -i '$a the last line' test.txt |
加上-i参数就是直接修改文件,为不是输出到console了
$是最后一行,$a就是在最后以后后新增的意思了
awk
将一行数据分成多个段来处理
格式
1 | awk '条件1{动作1} 条件2{动作2}...' 文件名 |
awk的处理流程是:
- 将文件第一行读入,并赋给变量$0,$1,$2…,awk默认的分割符是空格或tab
- 根据条件判断,执行动作
- 执行完所有动作
- 继续下一行
变量$0是一整行的数据,$1是第一分段数据
awk的内建变量:
NF:每一行($0)拥有的分段总数
NR:当前awk是在处理第几行
FS:当前的分隔符
自定义分隔符
通过FS=”:”可以设置分隔符为:
如
1 | $ last -n 5 |egrep -v '^$|wtmp' | awk '{FS=":"} {print $1 "\t all:" NF "\t now: " NR}' |
但是这样有个问题,就是第一行在执行的时候,分隔符还是空格,所以第一行的结果有问题
解决办法是使用关键字BEGIN
1 | [api@kfxqtyglpt ~]$ last -n 5 |egrep -v '^$|wtmp' | awk 'BEGIN {FS=":"} {print $1 "\t all:" NF "\t now: " NR}' |
条件
awk中可以使用条件运算符:>,<,>=,<=,==,!=
1 | [api@kfxqtyglpt ~]$ last -n 5 |egrep -v '^$|wtmp' | awk 'BEGIN {FS=":"} {printf $1 "\t all:" NF "\t now: " NR} NR>3 {printf "\t more than 3 \n"} NR<=3 {printf "\n"}' |
对大于3的行添加了一个输出。注意我这里使用了printf,要自己加上\n换行