linux文本处理三剑客:
linux正则表达式:用于快速过滤、替换需要的内容
linux三剑客:grep(文本抓取器)、sed(流编辑器)、awk(报表生成器)
基于grep
linux命令基于行处理
^winber
以winber开头
win$
以win结尾
^$
表示空行,不是空格
.
代表且只能代表任意一个字符 (其他功能:当前目录,加载文件)
\
转义字符,表示特殊字符
*
重复0个或多个前面的一个字符,不代表所有 (其它功能:通配符)
.*
匹配所有的字符,^.* 任意多个字符开头
[abc]
匹配字符集合内任意一个字符[a-z]
[^abc]
在中括弧里边表示非,不包含a或b或c
{n,m}
重复前一个字符n到m次,注意:grep 要对{}转义\{\},egrep不需要转义
grep
参数: -v 排除匹配的内容,-E 支持扩展的正则表达式,-i 忽略大小写,-o 只输出匹配的内容,
--color=auto 匹配的内容加颜色,-n 显示行号
示例:
利用sed的替换功能完成eth0的ip抽取:
ifconfig eth0 | grep 'inet addr' | sed 's#^.*r:##g' | sed 's# Bcast.*$##g’
优化:ifconfig eth0 | grep 'inet addr' | sed -n 's#^.*r:\(.*\) B.*$#\1#gp’
sed 参数:s 替换,g 全局,-i 修改文件,-n 取消默认输出,p 打印内容
提升示例(同时获取IP和广播地址)ifconfig eth0 | sed -rn 's#^.*addr:(.*) B.*t:(.*) M.*$#\1\t\2#gp’
这里边的#可以是任意分隔符
sed不同于vim,不需要用户交互,基于文本流处理,不需要把文件整个一次性加载到内存,逐行加入模式空间
语法: sed ‘范围(条件) 命令’ file
执行多个命令用’;'隔开
范围:使用数字,表示多少行,使用’,’表示到某一行,使用’~’表示跨多少行
可多次使用 s/old/new/g 进行迭代替换,old位置可以使用正则表达式,但new位置可以使用以下特殊字符:
&: 指代原来old部分的值
\U: 把\U后面所有字符变成大写 \L同理小写
\u: 把后面第一个字符改成大写 \l同理小写
\E:终止
把[]里小写的字符改成大写:sed ’s/\[.*\]/\U&/‘ smb.conf
分组(group):sed ’s/#\(ServerName\)/\1/p’ httpd.conf
a:在指定行的下一行添加一行 同理 i: 在上一行
在文件末尾增加一项配置:sed ‘$ a DNS1=192.168.36.1’ ifcfg-eth0
c: 整行替换
sed ‘/^#ServerName/c ServerName www.winbox.cc’ httpd.conf
y:单个字符映射替换 sed ‘2y/abc/XYZ’ aa
sed -i.bak ’s/tom/TOM/g’ bb 修改的同时备份成以bak为后缀的文件
如果修改原文件,使用-i的同时不要使用-n和p
我们所做的所有操作,并没有改变原文件
n:读取下一行
N:追加 也是读取下一行
合并多行并替换:sed ‘{N;s/win/WIN/g}’ aa
awk:
awk [options] ’script’ file1,file2..
awk [options] ‘PATTERN’ { action } file1,file2..
读入行依分隔符(默认空白符)分割,可用$n获取第n个字符串
awk变量:
RS(Record separator):输入行分隔符是换行符(可以把多行当成一行处理) 与ORS对应
FS(field separator):输入字段分隔符 与OFS对应
NR:相对于所有文件处于多少行
NF:当前行字段总数
在awk中打印变量不需要加$符号
在action中使用多个语句要用分号隔开
printf 能格式化输出
printf format file1,file2..
awk操作符:除了常用算数操作符还有 x**y 次方 等等
x ~ y:x能被y匹配到则为真
subscript in array :true if the array has an element with the subscript
难点:PATTERN和action
常见的模式类型:
1)正则表达式,格式:/regular/
2)expression 表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或 $1 == “mgtv”,用运算符~(匹配)或!~
3)指定的匹配范围,格式为 part1,part2
4)BEGIN/END 在整个脚本执行之前或之后执行一次命令
5)空模式 文件的每一行都做处理
常见的Action:
1)Expressions
2)Control statement
awk -F:-v sum=0 ‘{if ($3>=500) sum++}END{print sum}’ /etc/passed
while(遍历每一个字段)
awk -F: ‘{i=1;while(i<=NF) {if length($i)>=4} {print $i};i++}}’ /etc/passwd
do-while(bash没有这个语法)
for:awk -F: ‘$NF !~ /^$/{BASH[$NF]++}END{for(A in BASH){printf “%15s:%i\n”,A,BASH[A]}}’ /etc/passwd
switch(expression) { case VALUE or /REGEXP: statement1,statement2..}
next:提前结束对本行文本的处理,并接着处理下一行
array:数组下表不一定是数字,可以是任意字符串
for(var in array) 遍历数组