1、grep和egrep(过滤器)
grep:
grep [选项][匹配条件][file1 file2...] (在文件中查找)
command|grep[选项][匹配条件]
常用选项:
-v:不显示匹配行信息 -i:搜索时忽略大小写 -n:显示行号 -r:递归搜索 -E:支持扩展正则表达式 -F:不按正则表达式匹配,按照字符串字面意思匹配
不常用 选项:
-c:只显示匹配行总数 -w:匹配整词 -x:匹配整行 -l:只显示文件名,不显示内容 -s:不显示错误信息
使用示例:
grep "bin" shell/test1.sh //在文件test1.sh中查找bin内容 grep -E "bin|BIN" shell/test1.sh //查找bin或BIN
egrep:
grep默认不支持扩展正则表达式,值支持基础正则表达式
使用grep -E可以支持扩展表达式
使用egrep可以支持扩展表示是,等价于grep -E
2、sed(流编辑器)
sed的工作模式:
sed Stream Editor,流编辑器。对标准输出或文件逐行进行进行处理。
语法格式:
stdout | sed [option] "pattern command" //stout:标准输出; pattern:可选
sed [option] "pattern command" file //处理某个文件信息
sed的选项:
-n:只打印模式匹配行
sed 'p' sed.txt //遍历sed.txt文件的每一行然后打印,会打印原行,所以一行会打印2此,p:print(打印) sed -n 'p' sed.txt //同上,但不会打印原行 sed -n '/world/p' sed.txt //匹配包含world的行然后打印这行
-e:直接在命令进行sed编辑,默认选项(可以处理多次)
sed -n -e '/python/p' -e '/PYTHON/p' sed.txt //既匹配小写的python又匹配大写的PYTHON,然后打印
-f:编辑动作保存在文件中,指定文件执行
sed -n -f edit.sed sed.txt //'/python/p'写在edit.sed文件中,然后通过指定edit.sed文件来进行流编辑处理 //实际效果等同于: sed -n /python/p sed.txt
-r:支持扩展正则表达式
sed -n -r '/python|PYTHON/p' sed.txt
-i:直接修改文件内容
sed -n -i 's/python/py/g;p' sed.txt //把sed.txt文件中的python修改为py
set中的pattern详解(第4、5两种用的最多)
10command //匹配到第10行 10, 20command //匹配从第10行开始,到第20行结束 10,+5command //匹配从第10行开始,到第15行结束,打印第10行后在再打印5行 /pattern1/command //匹配到pattern1的行(满足pattern1条件的行) /pattern1/,/pattern2/command //匹配到pattern1的行开始,到匹配到pattern2的行结束 10,/pattern1/command //匹配从第10行开始,到匹配到pettern1的行结束 /pattern1/, 10command //匹配到pattern1的行开始,到第10行匹配结束
使用示例:
sed -n "10p" /etc/passwd sed -n "3,10p" /etc/passwd sed -n "3,+2p" /etc/passwd sed -n "/usbmux/p" /etc/passwd sed -n "/^usbmux/,/^whoopsie/p" /etc/passwd sed -n "6,/usbmux/p" /etc/passwd sed -n "/usbmux/,9p" /etc/passwd
sed中常用的编辑命令(command):
=:显示匹配内容的行号,不显示行内容 p:打印 a:行后追加(append) i:行前追加 r:外部文件读入,行后追加 w:匹配行写入外部文件 d:删除 s/pattern/string/:将行内第一个pattern替换为string s/pattern/string/g:将行内全部的pattern替换为string s/pattern/string/2:将行内第2个pattern替换为string s/pattern/string/2g:将行内从第2个pattern开始替换,所有的都替换为string s/pattern/string/ig:将行内pattern全部替换为string,忽略大小写
使用示例:
sed "/dream/d" dream.txt //在文件dream.txt中删除匹配到dream的行 sed -i "/lives/a I HAVE A DREAM" dream.txt //在文件dream.txt中匹配到lives的行后面追加'I HAVE A DREAM' sed -i "/dream/r test" dream.txt //将文件test的内容追加到在dream.txt文件中内容匹配到dream的行的后面 sed "/dream/w test" deram.txt //将dream.txt匹配到dream的行内容保存到test文件中
反向引用:
& :引用模式匹配到的整个串,不可以实现部分替换
\1(数字一):引用模式匹配到的整个串,可以实现部分替换
使用示例:
sed -i "s/had..p/&s/g" dream.txt //把文件dream中的所有hadxxp(had开头,p结尾,中间有两个字符)的在其后加's' sed -i "s/\(had..p\)/\1s/g" deram.txt //同上 sed -i "s/\(had\).../\1doop/g" dream.txt //部分替换,把had后的三个字符替换为'doop',替换所有
sed引用变量的注意事项:
①当匹配模式中存在变量,则建议使用双引号
②sed中需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号
利用sed查找文件内容:
例:统计mysql配置文件my.cnf有几个段,每段的段名 ,并统计每个段的参数个数
#!/bin/sh # file_name=/home/nginx/shell/testcnf.txt function get_all_segments { echo "`sed -n '/\[.*\]/p' $file_name | sed -e 's/\[//g' -e 's/\]//g'`" } function count_items_in_segment { echo "`sed -n '/\['$1'\]/,/\[.*\]/p' $file_name | grep -v ^\# | grep -v ^$ | grep -v "\[.*\]" | wc -l`" } for seg in `get_all_segments` do echo "peizhixuanxiang: $seg `count_items_in_segment $seg`" done
利用sed删除文件内容
10d //删除第10行 10, 20d //删除第10行,到第20行 10,+5d //删除第10行到第15行 /pattern1/d //删除匹配到pattern1的行(满足pattern1条件的行) /pattern1/,/pattern2/d //删除匹配pattern1的行,到匹配到pattern2的行 10,/pattern1/d //删除第10行,到匹配到pettern1的行 /pattern1/, 10d //删除匹配到pattern1的行,到第10行(不推荐使用) (单独一个'$'表示最后一行)
使用示例:
sed -i '/^#/d;/^$/d' nginx.conf //删除nginx.conf配置文件的所有注释行和空行('#'在第一个字符) sed -i '/[:blank:]*#/d' nginx.conf //删除'#'前有多个空格的行,[:blank:]:表示空格
所有不以'#'开头的行前加'*'
sed -i 's/^[^#]/\*&/g' //[^#]:非'#',&:反向引用
利用sed修改文件内容
(替换命令)old:既可以为普通字符串,也可以是正则表达式; new:只能是普通字符串 10s/old/new/ //把第10行的old内容替换为new 10, 20s/old/new/ //把第10行,到第20行的old内容替换为new 10,+5s/old/new/ //把第10行到第15行的old内容替换为new /pattern1/s/old/new/ //把匹配到pattern1的行的old内容替换为new /pattern1/,/pattern2/s/old/new/ /把匹配pattern1的行,到匹配到pattern2的行的old内容替换为new 10,/pattern1/s/old/new/ //把第10行,到匹配到pettern1的行的old内容替换为new /pattern1/, 10s/old/new/ //把匹配到pattern1的行,到第10行的old内容替换为new
利用sed往文件中追加内容
例:
在test.txt的第10行后追加'Add Line Behend'
sed -i '10a Add Line Behend' test.txt
3、awk
awk工作模式:(与sed类似)
awk是一个文本处理工具,通常用于处理数据并生成结果报告
语法格式:
awk 'BEGIN{}pattern{commands}END{}' file_name
standard output | awk 'BEGIN{}pattern{commands}END{}'
BEGIN{}:正式处理数据之前执行,固定写法
parttern:匹配模式
{commands}:处理命令,可能多行
END{}:处理完所有匹配数据后执行,固定写法
awk的内置变量:
$0 //整行内容 $1-$n //当前行的第1-n个字段(相当于用分隔符分割后的元素) NF //当前行的字段个数,也就是有多少列 (Number Field) NR //当前行的行号,从1开始计数 (Number Row) FNR //多文件处理时,每个文件行号单独计数,都是从0开始 (File Number Row) FS //输入字段分隔符。不指定默认以空格或tab键分割(Field Separator) RS //输入行分隔符。默认回车换行 (Row Separator) OFS //输出字段分隔符。默认为空格(output Field Separator) ORS //输出行分隔符。默认为回车换行 (output Row Separator) FILENAME //处理文件的文件名 ARGC //命令行参数个数 ARGV //命令行参数数组
例:
test.txt的第一行内容:root:x:0:0:root:/root:/bin/bash
awk '{print $0}' test.txt //输出test.txt的每一行内容 awk 'BEGIN{FS=":"}{print $1}' test.txt //以':' 分割每行内容,输出每一行的第一个字段,这里第一行会输出'root' awk 'BEGIN{FS=":"}{print NF}' test.txt //输出每一行字段个数,第一行有7个字段
awk格式化输出值printf
%s:打印字符串 %d:打印十进制数 %f:打印一个浮点数 %x:打印十六进制数 %o:打印八进制数 %e:打印数组的科学技术法形式 %c:打印单个字符串的ASCII码 -:左对齐(对其时要指定位数) +:有对齐 #:显示8进制在前面加0,显示16进制在前面加0x
使用示例:
awk 'BEGIN{FS=":"}{printf "%#x\n",$3}' /etc/pwass //以十六进制的形式输出每行的第三个字段,每个字段前加0x
awk模式匹配的两种用法:
第一种匹配模式:
RegExp
匹配/etc/passwd文件行中含有root字符串的所有行
awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
匹配/etc/passwd文件行中以yarn开头的所有行
awk 'BEGIN{FS=":"}/^yarn/{print $0}' /etc/passwd
第二种匹配模式:
关系运算符匹配:
< 小于 > 大于 <= 小于等于 >= 大于等于 == 等于 != 不等于 ~ 匹配正则表达式 !~ 不匹配正则表达式
(1)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50的所有行信息
awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd
(2)、以:为分隔符,匹配/etc/passwd文件中第3个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3>50{print $0}' /etc/passwd
(3)、以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的所有行信息
awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
(4)、以:为分隔符,匹配/etc/passwd文件中第7个字段不为/bin/bash的所有行信息
awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/passwd
(5)、以:为分隔符,匹配/etc/passwd中第3个字段包含3个以上数字的所有行信息
awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd
布尔运算符匹配:
|| 或
&& 与
! 非
(1)、以:为分隔符,匹配/etc/passwd文件中包含hdfs或yarn的所有行信息
awk 'BEGIN{FS=":"}$1=="hdfs" || $1=="yarn" {print $0}' /etc/passwd
(2)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第4个字段大于50的所有行信息
awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/passwd
awk中表达式的用法:
算数运算符:
+ 加
- 减
* 乘
/ 除
% 取模
^或** 乘方
++x 在返回x变量之前,x变量加1
x++ 在返回x变量之后,x变量加1
--x 在返回x变量之前,x变量减1
x-- 在返回x变量之后,x变量减1
(比较复杂的awk命令,可以写在文件中,然后通过 "awk -f [awK命令文件名]" 来执行)
awk动作中国的条件及循环语句:
条件语句:
if(条件表达式1)
动作
else if(条件表达式2)
动作
else
动作
循环语句:
while循环:
while(条件表达式)
动作
do while循环:
do
动作
while(条件表达式)
for循环:
for(初始化计数器;计数器测试;计数器变更)
动作
awk中的字符串函数:
length(str) 计算长度 index(str1,str2) 返回在str1中查询到的str2的位置 tolower(str) 小写转换 toupper(str) 大写转换 split(str,arr,fs) 分隔字符串,并保存到数组中(索引从1开始) match(str,RE) 返回正则表达式匹配到的子串的位置,正则表达式写在'//'内 substr(str,m,n) 截取子串,从m个字符开始,截取n位。n若不指定,则默认截取到字符串尾 sub(RE,RepStr,str) 替换查找到的第一个子串 gsub(RE,RepStr,str) 替换查找到的所有子串
awk的常用选项
-v 定义或引用变量,将外部变量引用到awk内
-f 指定awk命令文件(把awk命令放入文件,然后通过-f来指定这个文件来执行)
-F 指定分隔符
-V 查看awk的版本号
例:
num1=20 var1="hello world" awk -v num2=$num1 -v var2="$var2" 'BEGIN{print num2,var2}' //变量引用
awk中数组的用法
定义数组:array=("Allen" "Mike" "Messi" "Jerry" "Hanmeimei" "Wang") 打印元素: echo ${array[2]} //Messi 打印元素个数: echo ${#array[@]} //6 echo ${#array[*]} //6 打印元素长度: echo ${#array[3]} //5——Jerry元素 给元素赋值: array[3]="Li" 删除元素: unset array[2];unset array //注意数组下标问题,删除一个元素后,其他的元素的下标保持不变 分片访问: echo ${array[@]:1:3} //访问下标为1到3的元素 元素内容替换: ${array[@]/e/E} 只替换每个元素的第一个e;${array[@]//e/E} 替换所有的e
数组的遍历:
for a in ${array[@]};do echo $a;done
awk中数组遍历:
在awk中,使用数组时,不仅可以使用1.2..n作为数组下标,也可以使用字符串作为数组下标
当使用1.2.3..n做为下标时,直接使用array[2]访问元素;需要遍历数组时,使用以下形式:
str="Allen Jerry Mike Tracy Jordan Kobe Garnet" split(str,array) for(i=1;i<=length(array);i++) print array[i]
awk 'BEGIN{str="Allen Jerry Mike Tracy Jordan Kobe Garnet";split(str,array);for(i=1;i<=length(array);i++) print array[i]}'
当使用字符串作为数组下标时,需要使用array[str]形式访问元素;遍历数组时,使用以下形式:
array["var1"]="Jin"
array["var2"]="Hao"
array["var3"]="Fang"
for(a in array) //推荐使用这种方法遍历数组
print array[a] //字符串数组下标只能用这种方式遍历
awk 'BEGIN{array["var1"]="Jin";array["var2"]="Hao";array["var3"]="Fang";for(a in array) print array[a]}'