simonid
1/1/2018 - 6:06 AM

sed&awk学习

sed&awk学习

正则表达式大全

转载自:
最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等等

一、校验数字的表达式

1 数字:^[0-9]*$
2 n位的数字:^\d{n}$
3 至少n位的数字:^\d{n,}$
4 m-n位的数字:^\d{m,n}$
5 零和非零开头的数字:^(0|[1-9][0-9]*)$
6 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
7 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
8 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
9 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
10 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
11 非零的正整数:^[1-9]\d*$^([1-9][0-9]*){1,3}$^\+?[1-9][0-9]*$
12 非零的负整数:^\-[1-9][]0-9"*$^-[1-9]\d*$
13 非负整数:^\d+$^[1-9]\d*|0$
14 非正整数:^-[1-9]\d*|0$^((-\d+)|(0+))$
15 非负浮点数:^\d+(\.\d+)?$^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
16 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
17 正浮点数: ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
18 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
19 浮点数:^(-?\d+)(\.\d+)?$^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$



二、校验字符的表达式

1 汉字:^[\u4e00-\u9fa5]{0,}$
2 英文和数字:^[A-Za-z0-9]+$^[A-Za-z0-9]{4,40}$
3 长度为3-20的所有字符:^.{3,20}$
4 由26个英文字母组成的字符串:^[A-Za-z]+$
5 由26个大写英文字母组成的字符串:^[A-Z]+$
6 由26个小写英文字母组成的字符串:^[a-z]+$
7 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
8 由数字、26个英文字母或者下划线组成的字符串:^\w+$^\w{3,20}$
9 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
10 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
11 可以输入含有^%&',;=?$"等字符:[^%&',;=?$\x22]+
12 禁止输入含有~的字符:[^~\x22]+



三、特殊需求表达式

1 Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
2 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
3 InternetURL:[a-zA-z]+://[^\s]*^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
4 手机号码:^(13[0-9]|14[0-9]|15[0-9]|166|17[0-9]|18[0-9]|19[8|9])\d{8}$
5 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
6 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
7 18位身份证号码(数字、字母x结尾):^((\d{18})|([0-9x]{18})|([0-9X]{18}))$
8 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
9 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
10 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
11 日期格式:^\d{4}-\d{1,2}-\d{1,2}
12 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
13 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
14 钱的输入格式:
15 1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
16 2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
17 3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
18 4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
19 5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
20 6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
21 7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
22 8.1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
23 备注:这就是最终结果了,别忘了"+"可以用""替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
24 xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
25 中文字符的正则表达式:[\u4e00-\u9fa5]
26 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
27 空白行的正则表达式:\n\s
\r (可以用来删除空白行)
28 HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
29 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
30 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
31 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
32 IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
33 IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))



sed学习

一般格式

命令行格式

sed [options] 'command' filename

options:
-e、-n

command:行定位(正则)+sed命令

脚本格式

sed -f script filename

注意:使用sed很多情况下并不会修改源文件的内容,只是改变输出内容

行定位

1.p命令:打印出相关行

sed 'p' passwd

这样会打印出两行,原因是sed是读入一行输出一行的

2.-n:弥补上述问题,指打印出相关的一行

sed -n 'p' passwd

打印指定行数的行:

sed -n '2p' passwd
# 打印passwd文件的第二行

打印指定行数范围的行:

nl passwd | sed -n '2,3p'
#打印passwd文件中2-3内容

打印含指定内容的行:

sed -n '/test/p' passwd
# 打印出passwd文件含'test'的行

ls -l | sed -n '/Dcoker/p'
# 打印出含'Docker'字样的文件

打印指定行内容范围的行:

nl passwd | sed -n '/aa/,/bb/p'
# 打印所有行中含aa的行到含bb的行的行内容

取反操作:
加上!就可以了

sed -n '2!p' passwd
# 打印除第二行外的内容

间隔输出:

nl passwd | sed -n '1~2p'
# 打印奇数行

打印错误日志:

sed -n '/Error/p'

行处理

基本命令:
-a(新增行)
-i(插入行)
-c(替代行)
-d(删除行)


新增行:

nl passwd | sed '3a ====='
#第三行后增加分割符

nl passwd | sed '1,5a ====='
# 第一到第五行都增加分隔符

插入行:
插入操作和新增类型,不过插入是在指定行前面增加

替代行:

nl passwd | sed '2c hello'
# 将第二行内容替换为hello

nl passwd | sed '3,10c hello'
# 3到10行的内容全部替换为只有一行的hello,注意不是每一行替换,是整体替换

删除行:

nl passwd | sed '/test/d'
# 删除含test内容

sed的操作命令类似vi,那么我们完全可以使用sed来替代vi

比如需要在ssh_config文件中加入一些用户设置信息

sed '$a \  Port 12345 \n  PermitRootLogin no' ssh_config
# 增加
Port 12345
PermitRootLogin no

删除空行:

sed '/^$/d' test.txt

操作命令

替换

格式:
-s : 分隔符/,#等
-g : 全局替换,如果前面没有加上这个,那么只是替换第一个匹配的

sed 's/false/true/' passwd
#将文件中的false替换为true

实践 打印出网卡的IP:

总体:
ifconfig eth0 | sed -n '/inet /p' | sed 's/inet.*r://' | sed 's/B.*$//'


分布剖析
ifconfig eth0 | sed -n '/inet /p':截取eth0的网卡IP所在行信息
          inet addr:104.233.105.212  Bcast:104.233.105.255  Mask:255.255.255.0

ifconfig eth0 | sed -n '/inet /p' | sed 's/inet.*r://':截取前面信息除去inet addr的信息
          104.233.105.212  Bcast:104.233.105.255  Mask:255.255.255.0

最后一个类似,除去Bcast后的信息

高级操作命令

{command1;command2}:多个命令
其中:
{}内加入n就是调到下一行

nl passwd | sed '{20,30d;s/false/true/}'
# 删除20到30行内容,并替换所有false为true

nl passwd | sed -n '{n;p}'
# 打印偶数行

nl passwd | sed -n '{p;n}'
# 打印奇数行

&符号使用
替换固定字符串

sed 's/^[A-Za-z0-9_-]\+/&  /' passwd
# 将passwd文件中的用户名后增加空格

sed 's/^[a-z_-]\+/\u&/' passwd
# 将开头的小写字母转换为大写

ls *.txt | sed 's/^\w\+/\U&'
# 将txt文件名改为全大写

()的使用
后面的\1,\2,... 按顺序代表前面的\( \)中的内容

sed 's/\(^[A-Za-z0-9_-]\+\):x:\([0-9]\+\):\([0-9\\+\):.*$/USER:\1  UID:\2  GID:\3/' passwd
# 获取passwd文件中的用户名及其UID、GID

-r-w使用:

-r:复制指定文件插入到匹配行
-w:复制匹配行拷贝指定文件里(覆盖写入,源文件内容会删除后增加新内容)

sed '1r a.txt' b.txt
# 将a.txt的内容插入到b.txt文件的第一行后面(不改变源文件内容,只是改变输出)

sed '1w a.txt' b.txt
# 将b.txt的第一行覆盖写入a.txt

q提前结束:

nl tmp.log | sed '/false/'
# 

awk学习

格式:
sed一致分为命令行和脚本模式

内置参数使用

内置变量

内置变量1

$0、$1、$2...:分别表示当前行、每行第一个字段、每行第二个字段....

分隔符:

options:-F 分隔符(默认为空格)

demo:

awk -F ':' '{print $1}' /etc/passwd
# 分隔符是:,输出第三个字段,也就是用户名

awk -F ':' '{print $1,$2}' /etc/passwd
# 输出第一和第二字段,之间通过空格分隔

前面的sed方法输出用户名、UID、GID需要借助()实现,内容很长,这里可以用awk简化
awk -F ':' '{print "User:"$1 " " "UID:"$3}' passwd

内置变量2

NR:每行的记录号,行号
NF:字段的数量变量,列号

内置参数demo

显示/etc/passwd每行的行号,每行的列数,对应行的用户名

awk -F ':' {print "Line:"NR,"Col:"NF,"User:"$1}' passwd

awk -F ':' '{printf("Line:%s Col:%s User:%s\n",NR,NF,$1)}' passwd

显示/etc/passwd中UID大于100的行号和用户名

awk -F ':' '{if ($3>100) print "Line:"NR,"User:"$1}' passwd

在日志中找出Error的时间信息

sed '/Error/p' tmp.log | awk '{print $1}'

awk '/Error/{print $1}' tmp.log

逻辑判断式

awk -F ':' '$1~/^m.*/{print $1}' passwd
# 匹配第一个字段开头为m的内容并打印

awk -F ':' '$1!~/^m.*/{print $1}' passwd
# 匹配第一个字段开头非m的内容并打印
awk -F ':' '$3>100{print $1,$3}' passwd
# 查找除UID大于100的用户名和UID

扩展格式

基本格式:
awk command 'BEGIN{print xxx}{print xxx}END{print xxx}' filename

案例1:
制表显示/etc/passwd每行的行号,每行的列数,对应行的用户名

awk -F ':' 'BEGIN{print "Line Col User"}{print NR,NF,U$1}END{print"-----"FILENAME"-----"}' passwd

awk案例

计算所有文件的容量总和

ls -l | awk 'BEGIN{size=0}{size+=$5}END{print " size is " size/1024}'

统计显示/etc/passwd中账户的总数

awk -F ':' 'BEGIN{count=0}$1!~/^$/{count++}END{print "count=" count}' passwd

统计显示UID大于100的用户名

awk -F ':' 'BEGIN{count=0}{if ($3 > 100) name[count++]=$1}END{for (i=0;i<count;i++) print i,name[i]}' passwd

统计netstat -anp状态下为LISTENCONNECTED的连接数量

netstat -anp | awk '$6~/CONNECTED|LISTEN/{cum[$6]++}END{for (i in sum) print i,sum[i]}'

统计一个目录下的指定格式的文件总数:

find -name "*.azw3" -print | awk -F ' ' 'BEGIN{count=0}{count++}END{print "azw3 total number =" count}'

查看目录下大于指定容量的文件名及数量

ls -l | awk 'BEGIN{i=0} {if($5>40*1024*1024){filename[i++]=$9;}} END{print "total:"i;for(j=0;j<i;j++){print "filename:"filename[j];}}'
# 查看大于大于40M的

总结

sed和awk的区别
sed侧重于配合正则表达式一起使用
awk侧重于复杂的逻辑表达式使用