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 [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/'
#
格式:
和sed
一致分为命令行和脚本模式
$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
NR
:每行的记录号,行号
NF
:字段的数量变量,列号
显示/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
计算所有文件的容量总和
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
状态下为LISTEN
和CONNECTED
的连接数量
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侧重于复杂的逻辑表达式使用