markdown SED与AWK学习

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown SED与AWK学习相关的知识,希望对你有一定的参考价值。

# 正则表达式大全

转载自:<br>
[最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等等](http://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html)<br>

### 一、校验数字的表达式

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

<br><br>

### 二、校验字符的表达式

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

<br><br>


### 三、特殊需求表达式

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

<br><br>
# sed学习

### 一般格式
#### 命令行格式
```
sed [options] 'command' filename
```

options:<br>
-e、-n  <br>

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

#### 脚本格式
```
sed -f script filename
```


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

### 行定位
1.p命令:打印出相关行<br>
```
sed 'p' passwd
```
这样会打印出两行,原因是sed是读入一行输出一行的<br>

2.-n:弥补上述问题,指打印出相关的一行<br>
```
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的行的行内容
```

取反操作:<br>
加上`!`就可以了
```
sed -n '2!p' passwd
# 打印除第二行外的内容
```

间隔输出:
```
nl passwd | sed -n '1~2p'
# 打印奇数行
```

打印错误日志:
```
sed -n '/Error/p'
```

### 行处理

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

<br>

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

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

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

替代行:
```
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<br>

比如需要在`ssh_config`文件中加入一些用户设置信息
```
sed '$a \  Port 12345 \n  PermitRootLogin no' ssh_config
# 增加
Port 12345
PermitRootLogin no
```

删除空行:
```
sed '/^$/d' test.txt
```

### 操作命令

#### 替换
格式:<br>
-s : 分隔符/,#等<br>
-g : 全局替换,如果前面没有加上这个,那么只是替换第一个匹配的<br>
```
sed 's/false/true/' passwd
#将文件中的false替换为true
```

<b>实践</b>
打印出网卡的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}:多个命令<br>
其中:<br>
{}内加入`n`就是调到下一行<br>

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

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

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

`&`符号使用<br>
替换固定字符串<br>

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

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

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

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

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

`-r`、`-w`使用:<br>

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

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

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

`q`提前结束:<br>

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



# awk学习

格式:<br>
和`sed`一致分为命令行和脚本模式<br>

### 内置参数使用

#### 内置变量

#### 内置变量1
`$0、$1、$2...`:分别表示当前行、每行第一个字段、每行第二个字段....
<br>

分隔符:<br>

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

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`:每行的记录号,行号<br>
`NF`:字段的数量变量,列号<br>

#### 内置参数demo

显示`/etc/passwd`每行的行号,每行的列数,对应行的用户名<br>
```
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
```

### 扩展格式

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

案例1:<br>
制表显示`/etc/passwd`每行的行号,每行的列数,对应行的用户名<br>
```
awk -F ':' 'BEGIN{print "Line Col User"}{print NR,NF,U$1}END{print"-----"FILENAME"-----"}' passwd
```

### awk案例

计算所有文件的容量总和<br>
```
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的用户名<br>
```
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的区别<br>
sed侧重于配合正则表达式一起使用<br>
awk侧重于复杂的逻辑表达式使用<br>

以上是关于markdown SED与AWK学习的主要内容,如果未能解决你的问题,请参考以下文章

linux学习:sed与awk与tr用法整理

[Linux Shell学习系列十四]sed和awk-6.awk与Shell

[Linux Shell学习系列十四]sed和awk-5.awk基础

linux 下的 正则表达式(awk,sed,awk)学习

学习sed,awk最好的路径

shell脚本学习总结----sed+grep+awk+正则