linux三大神器:sed(行处理)grep(查找)awk(文本处理)
三个学习阶段:正则表达式->sed基本处理->awk(更复杂的处理)
一、正则表达式
1. 应用场景:
查找、取出、匹配符合条件的某个字符或字符串
2. 字符:
2.1 特定字符(某个具体的字符)
2.2 范围内字符 单个字符[]
数字字符 [0-9]
小写字符 [a-z][A-Z]
取反 [^]
例:
grep '[0-8]' file
grep '[a-zA-Z]' file
grep '[^0-9]' file
grep '[[:space:]]' file // 匹配所有空白字符(回车及空格)
grep '[[:punct:]]' file // 匹配所有特殊字符
grep '[[:alpha:]]' file // 匹配所有大小写字母
grep '[[:alnum:]]' file // 匹配所有大小写字母及数字
2.3 任意字符 .
grep '\.' file == grep '[.]' file // 匹配小数点
grep '.' file // 匹配所有
2.4 边界字符
grep '^1' file // 匹配以1开头的所有字符
grep '1$' file // 匹配以1结尾的所有字符
grep '^$' file // 匹配所有空行
2.5 元字符
grep '\w' file // 匹配任何字类字符:数字、字母、下划线
grep '\W' file // 匹配任何非字类字符
grep '\b[0-9][0-9]\b' file // 匹配任意两位数
3. 字符组合
3.1 重复
* : 零次或多次匹配前面的字符或子表达式
+ : 一零次或多次匹配前面的字符或子表达式
? : 零次或一次匹配前面的字符或子表达式
()、{} : 使用时需转义
grep 'se*' file
grep 'se\+' file
grep 'se\?' file
grep '\(se\)*' file // 一起匹配se,有空行会匹配到
grep '\(se\)+' file // 一起匹配se,有空行不会匹配到
3.2 重复特定次数
{n,m} : 至少n次,至多m次
* : {0,}
+ : {1,}
? : {0,1}
grep '[0-9]\{3,4\}' file // 匹配数字三到四次
3.3 逻辑的表示
| : 或
grep 'bin/\(true|false\)' file // 匹配bin后面出现true或false的所有数据
4. 案例
4.1 匹配4到10位的qq号
grep '^[0-9]\{4,10\}$' file
4.2 匹配15到18位身份证号(包括X)
grep '^[1-9]\([0-9]\{13\}|[0-9]\{16\}\)[0-9xX]$' file
4.3 匹配密码//(由数字,26字母和下划线组成)
grep '^\w\+$' file
二、sed学习内容:
1. sed是如何进行文本处理的
2. sed的基本操作指令: 文本的行处理(增、删、替)、字符串替换(取用)
sed-行处理:
一次处理一行内容
sed不改变文件内容(除非重定向)
sed-格式:
命令行格式 : sed [option] 'command' file(s)
[option]: -e(默认选项); -n(打印相关的行)
command : 行定位(正则)+sed命令(操作)
1 sed命令 -p :
-p (打印[第几]行)
例:
sed 'p' file // 会将file的信息打印于屏幕,每条数据输出两次
sed -n 'p' file // 打印相关的行
1.1 定位一行: x(行号) or /正则/
例:
使用行号
sed -n '10p' file // 打印第十行(一定要与-n连用,否则会使用默认选项,打印两次)
nl file | sed -n '10p' // 打印第十行并标行号
使用正则
sed -n '/root/p' file // 打印包含root的行
1.2 定位多行:x,y(从x行到y行) or /第一个正则匹配表达式行/,/第二个正则匹配表达式行/
例:
使用行号
nl file | sed -n '10,20p' // 打印10行到20行
使用正则
nl file | sed -n '/news/,/mooc/p' // 打印从news行到mooc行
nl file | sed -n '10!p' // 不打印第十行
nl file | sed -n '10,20!p' // 不打印第十行到第二十行
1.3 定位间隔几行: first~step
例:
nl file | sed -n '1~2p' // 从第一行、间隔2行开始打印
2 行处理命令: -a(新增行)/i(插入行) -c(替代行) -d(删除行)
注: -a (行之后新增) -i (行之前追加)
nl file | sed '1a ===========' // 在第一行后新增=====分隔符
nl file | sed '1,5a ===========' // 在第一行至第五行后新增=====分隔符
nl -b a file | sed '10c 测试替换' // 将第十行改为测试替换(-b a 空行也输出编号)
nl -b a file | sed '10,20c 测试替换' // 第十行到第二十行会一起替换成测试替换
nl -b a file | sed '10d' // 删除第十行
nl -b a file | sed '/news/d' // 删除news行
sed '/^$/d' file // 删除空行
sed '$a\ 文件末尾增加内容1\n 内容2|n 内容3' file // a后面的空格需转义
sed -n '/error/p' file.log // 将日志文件中含error的打印出来
3 行替换命令:
-s 替换, 分隔符 / or #
-g 全局替换
sed 's/原字符/新字符/' file // 将元字符替换成新字符(替换一次)
sed 's/元字符/新字符/g' file // 全局替换
案例:获取ip
sed -n '/IPv4/p' ipconfig | sed 's/IPv4//' | sed 's/.*://' | sed -n '/\w.*/p'
sed -n '/IPv4/p' ipconfig | sed 's/IPv4//' | sed 's/.*://' | sed -n '/\([1-9]\{3\}\).*/p'
4 高级操作命令
4.1
{}: 多个sed命令,用;隔开
sed '{5,10d;s/false/true/}' file // 删除第五到10行,将false替换为true
4.2
n : 读取下一个输入行(用下一个命令进行处理)
nl file | sed -n '{n;p}' // 打印偶数行
nl file | seq -n '2~2p'
nl file | sed -n '{p;n}' // 打印奇数行
nl file | sed -n '1~2p'
nl -b a file | sed -n '{n;n;p;n}' // 打印隔n行
4.3
& : 替换固定字符串
sed 's/^[a-z-_]\+/& /' file // 用&代替前面的正则,在加空格
sed 's/^[a-z-_]\+/\u&/' file // 将匹配的首字母转换为大写
sed 's/^[a-z-_]\+/\U&/' file // 将匹配的字母全转换为大写
sed 's/^[a-z-_]\+/\l&/' file // 将匹配的首字母转换为小写
sed 's/^[a-z-_]\+/\L&/' file // 将匹配的字母全转换为小写
ls *.txt | sed 's/\w\+/\U&/' // 将txt文件前缀全大写
ls *.txt | sed 's/\w\+/\u&/' // 将txt文件前缀首字母大写
4.4
\(\): 替换某部分字符串
sed 's/\([a-z-_]\+\):x:\([0-9]\+\)/USER:\1 PID\2' file
4.5
-r : 复制指定文件插入到匹配行,不重定向的话不会改变文件内容
-w : 复制匹配行写入到制定文件里,会改变写入文件的内容
sed '1r 123.txt' abc.txt // 将123的内容写入到abc第一行后
sed '1w 123.txt' abc.txt // 将abc文件的第一行内容写入到123文件中
sed 'w 123.txt' abc.txt // 将abc文件的全部内容写入到123文件中
4.6 q : 退出sed
nl file | sed '10q' // 到第十行停止打印
nl file | sed '/false/q' // 找到第一个false即停止打印
三、awk处理方式:
一次处理一行内容
可对每行切片处理
awk '{print $1}' // 输出首个单词
1. awk使用格式
基本格式: awk [options] 'commond' files
'commond' : pattern {awk 操作命令}
pattern :正则表达式、逻辑判断式
awk '/Error/{print $1}' file // 正则判断error行并打印第一个元素
2. awk 内置参数使用:
$0 : 表示当前整个行
$1 : 每行第一个字段
$2 : 每行第二个字段
options:
F 制指定分隔符,默认为空格
NR : 每行的记录号 行号
NF : 字段数量变量 列号
$NF : 最后一个字段
替换jname空格为"_"
gawk 'BEGIN{FS="\t";OFS="\t"}{gsub(/ /,"_",$10);print $0}' 2018.csv >> 2018new.csv
RS:记录行分隔符
ORS:可以看成RS的逆向过程
FS:字段分隔符
OFS:输出的字段分隔符
FILENAME : 正在处理的文件名
awk -F ':' '{print $1,$2}' files or awk -F ':' '{print $1"\t"$2}' files
awk -F ':' '{print "USER:"$1"\t""USERID"$2}' file
awk -F ':' '{print NR,NF}' file // 打印行号列号
awk '{print $NF}' txt.txt //显示最后一个字段
案例:
awk -F ':' '{print "Lines:"NR,"COLS:"NF,"USERID:"$1}' file
awk -F ':' '{printf("Lines:%3s Cols:%s USERID:%s\n",NR,NF,$1)}' file
awk -F ':' '{if ($2 > 100) print "LINES "NR,"COLS "NF}' file
sed -n '/Error/p' file | awk '{print $1}'
awk '/Error/{print $1}' file
3. awk 逻辑判断式
~,!~ : 匹配正则表达式
==,!=,>,< : 判断逻辑表达式
awk -F ':' '$1~/[^0-9]/{print $1}' file
awk -F ':' '$2>5{print $0}' file
awk 扩展格式
awk -F ':' 'BEGIN{print "LINES COLS USERID"}{print NR,NF,$1}END{print "----------"FILENAME"--------"}' file
ll | awk 'BEGIN{size=0}{size+=size+$5}END{print "size is " size/1024/1024"m"}'
// 统计文件行不为空的个数
awk -F ':' 'BEGIN{count = 0}$1!~/^$/{count ++ }END{print "count ="count}' file
// 统计文件id大于3的名字
awk -F ':' 'BEGIN{count=0}{if($1>3)name[count++]=$2}END{for(i=0;i<count;i++)print i,name[i]}' seq
awk -F ':' 'BEGIN{count=0}{if($1>3)name[count++]=$2}END{for(i in name)print i,name[i]}' seq
// 打印文件true和false出现的次数
awk -F ':' '$1~/true|false/{sum[$1]++}END{for(i in sum)print i,sum[i]}' seq
awk '/^book/' txt.txt //匹配含有book的每一行
awk '/[0-9]/' txt.txt //匹配含有数字的每一行
awk -F':' '/^book/{print $2}' //匹配以:为分割的符合条件的第二个元素并输出
awk -F':' '/^book/{print $NF}' //显示最后一列
awk -F':' '/^book/{print NR.$0}' #统计行数对行直接编号
cat file.txt|awk '{a[$1]=a[$1]+$2}END{for(i in a){print i,a[i]}}'/ #数组求和
seq 10 > file
cat file | awk 'NR%2==1' #取奇数行
cat file | awk 'NR%2==0' #取偶数行
cat file | awk '{a[NR]=$0}END{for(i=1;i<=NR;i+=2){print a[i]}}' #数组方式获取奇数行
cat file | awk '{a[NR]=$0}END{for(i=1;i<=NR-2;i++){print a[i]}}' #不要最后几行
seq 10 >> file
cat file | awk '!a[$0]++' #数组去重
cat file | awk '++a[$0]==1' #数组去重
cat file |sort -n|awk '{a[$1]++}END{for(i in a){print i,a[i]}}' #数组计数
cat file | awk '{a[$1]+=1}END{for(i in a){print i,a[i]}}'|sort -nr -k 1
四、awk vs sed
awk与sed都可处理文本
awk侧重于复杂的逻辑处理
sed侧重于正则的处理