文本处理工具:
grep: 文本过滤工具(模式:pattern)
sed: 流编辑器,文本编辑工具
awk: 文本报告生成器(格式化文本)
正则表达式:Regual Expression , REGEXP
基本正则表达式
扩展正则表达式
grep:
文本搜索工具,根据用户指定的”模式“(过滤条件),对目标文本逐行进行匹配检查,打印匹配的行
options:
-i: 忽略大小写
-o: 仅显示匹配到的字符串
-v: 显示不能匹配到的行
-E: 支持扩展的正则表达式
-q: 静默模式,不输出任何信息
-A #: 匹配到的行后#行
-B #:匹配到的行前#行
-C #: 匹配到的行前后#行
基本正则表达式的元字符:
字符匹配:
.: 匹配任意单个字符
[]:匹配指定范围内的任意单个字符
[^]:匹配指定范围外的任意单个字符
[:digit:], [:lower:], [:upper:], [:alpha:], [:alnum:], [:punch:], [:space:]
匹配次数:
*: 匹配前面字符任意次
.*: 匹配任意长度的任意字符
\?: 匹配前面的字符0次或1次
\+: 匹配前面的字符1次或多次
\{m\}: 匹配前面的字符m次
\{m,n\}: 匹配前面的字符至少m次,至多n次
\{0,n\}: 至多n次
\{m,\}: 至少m次
位置锚定:
^: 行首锚定,用于模式的最左侧
$: 行尾锚定,用于模式的最右侧
^PATTERN$: 用PATTERN来匹配整行
^$: 空白行
^[[:space:]]*$: 空行
\<: 词首锚定,用于单词的左侧
\>: 词尾锚定,用于单词的右侧
\<PATTERN\>: 匹配完整单词
分组和引用:
\(\): 将一个或多个字符捆绑,当作一个整体处理\(xy\)
后向引用:引用前面分组括号中的模式匹配到的字符\1, \2, ...
或:
a\|b
[ab]
egrep:
扩展的正则表达式
字符匹配:
.: 匹配任意单个字符
[]:匹配指定范围内的任意单个字符
[^]:匹配指定范围外的任意单个字符
[:digit:], [:lower:], [:upper:], [:alpha:], [:alnum:], [:punch:], [:space:]
匹配次数:
*: 匹配前面字符任意次
.*: 匹配任意长度的任意字符
?: 匹配前面的字符0次或1次
+: 匹配前面的字符1次或多次
{m}: 匹配前面的字符m次
{m,n}: 匹配前面的字符至少m次,至多n次
{0,n}: 至多n次
{m,}: 至少m次
位置锚定:
^: 行首锚定,用于模式的最左侧
$: 行尾锚定,用于模式的最右侧
^PATTERN$: 用PATTERN来匹配整行
^$: 空白行
^[[:space:]]*$: 空行
\<: 词首锚定,用于单词的左侧
\>: 词尾锚定,用于单词的右侧
\<PATTERN\>: 匹配完整单词
分组和引用:
(): 将一个或多个字符捆绑,当作一个整体处理(xy)
后向引用:引用前面分组括号中的模式匹配到的字符\1, \2, ...
或:
a|b: a或者b
C|cat: C或cat
[C|c]at: Cat或cat
[Cc]at: Cat或cat
练习:
找出/proc/meminfo文件中,所有以大小写s开头的行
grep -i "^s" /proc/meminfo
grep "^[sS]" /proc/meminfo
grep -E "^(s|S)" /proc/meminfo
显示当前系统上root,centos,user1用户的相关信息
egrep "^(root|centos|user1)\>" /etc/passwd
找出/etc/rc.d/init.d/functions中某单词后跟一个小括号的行
egrep -o "[_[:alnum:]]+\(\)" /etc/rc.d/init.d/functions
使用echo输出一个绝对路径,取基名
echo /etc/sysconfig/ | egrep -o "[^/]+/?$"
找出ifconfig命令结果中1-255之间的数值
ifconfig | egrep -o "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>"
取分区利用率最大值
df | grep "/dev/sd" | grep -o "[0-9]\{1,3\}%" | grep -o "[0-9]\+" | sort -nr | head -n1
过滤空行
grep -v "^[[:space:]]*$" f1
第一列与最后一列相同
grep "^\(.*\):.*/\1$" /etc/passwd
egrep "^([^:]+\>).*\1$" /etc/passwd
取ip
0-9 10-99 100-199 200-249 250-255
ifconfig ens33 |egrep "\<(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>" -o
ifconfig ens33 | sed -n '2p'| sed -r 's/.*inet (.*) net.*/\1/'
ifconfig ens33 | sed -n '2p'| sed -e 's/.*inet //' -e 's/ netmask.*//'
ifconfig ens33 | sed -r '2!d;s/.*inet (.*) net.*/\1/'
fgrep: 不支持正则表达式元字符
当不需要用到元字符去编写模式时,使用fgrep必能更好
sed
-n: 不输出模式空间中的内容至屏幕(没有匹配到就不显示)
-e: 多点编辑
-f
-r: 扩展的正则表达式
-i: 直接编辑原文件
d: 删除模式空间内容
p: 显示模式空间中内容
a \text: 在匹配到的行后面追加"text",支持\n追加多行
i \text: 在匹配到的行前面插入"text",支持\n追加插入
c \text: 把匹配到的行替换为“text”
w /PATH/TO/FILE: 保存模式空间匹配到的行至文件中
r /PATH/FROM/FILE: 读取文件内容至被模式匹配到的行后面
=: 为匹配到的行打印行号
!: 条件取反
s///: 查找替换,分隔符可自行制定,s@@@,s###
替换标记
g: 全局替换
w /PATH/TO/FILE: 将替换成功的结果保存至指定文件
p: 显示替换成功的行
地址定界
空地址:对全文进行处理
单地址:
#:指定行
/pattern/: 被此模式匹配到的每一行
地址范围:
#,#
#,+#
#,/pattern/
/pattern1/,/pattern2/
$: 最后一行
步进:~
1~2:奇数行
2~2:偶数行
高级编辑命令
h: 把模式空间中的内容覆盖之保持空间中
H: 把模式空间中的内容追加之保持空间中
g: 把保持空间中的内容覆盖之模式空间
G: 把保持空间中的内容追加之模式空间
x: 把模式空间中的内容与保持空间中的内容互换
n: 覆盖读取匹配到的行的下一行至模式空间中
N: 追加读取匹配到的行的下一行至模式空间中
d: 删除模式空间中的行
D: 删除多行模式空间中的所有行
事例:
sed -n 'n;p' FILE: 显示偶数行
sed '1!G;h;$!d' FILE: 逆序显示文件的内容
sed '$!d' FILE: 取出最后一行
sed '$!N;$!D' FILE: 取出文件后两行
sed '/^$/d;G' FILE: 删除原有的所有空白行,而后为所有的非空白行后添加一个空白行
sed 'n;d' FILE: 显示奇数行
sed 'G' FILE: 在原有的每行后添加一个空白行
echo "/var/log/messages/" | sed -r 's@[^/]+/?$@@'
cat /etc/httpd/conf/httpd.conf | sed -r 's/#(Name.*)/\1/' | sed -r 's/#(<[/]?Vir.*)/\1/'|sed -r 's/#([[:space:]]{2,}.*)/\1/'
cat /etc/httpd/conf/httpd.conf | sed -e '/^#NameVirtualHost/s/#//' -e '/^#<VirtualHost/,/^#<\/VirtualHost>/s/#//'
ls *.rpm | sed -r 's/.*\.(.*)\.rpm/\1/' |sort|uniq -c
ls *.rpm | rev|cut -d. -f2 |rev|sort|uniq -c
ls *.rpm |egrep -o "[^.]+\.rpm" |cut -d. -f1|sort|uniq -c
n和n+1合成一行
seq 1 10 | xargs -n2
df | sed -rn 's/^\/dev\/sd.*[ ]+([0-9]{1,3})%.*/\1/p'
cat /etc/centos-release | sed -re 's/([0-9]+).*/\1/' -e 's/.*([[:digit:]]+)/\1/'
awk:
awk [options] 'program' FILE...
program: PATTERN{ACTION STATMENT;STATMENT}
-F: 指明输入时用到的字段分隔符;默认为空白字符
-v var=value: 自定义变量
print:
print item1, item2, ...
逗号分隔符
输出的item可以时字符串,数值,记录的字段,变量或awk表达式
如省略item,相当于print $0, 打印整行
变量:
内建变量
FS: 输入字段分隔符, 默认空白字符
OFS:输出字段分隔符,默认空白字符
RS:输入行分隔符
ORS:输出行分隔符
NF:每一行字段数量
NR:行数
FNR:各文件分别记录行数
FILENAME
ARGC:命令行参数个数
ARGV:数组,保存命令行所给定的各参数;ARGV[0]第一个参数
自定义变量
-v var=value
在program中定义
printf: 格式化输出:printf FORMAT, item1, item2, ...
FORMAT必须给出
不会自动换行,需要\n
FORMAT中需要分别为后面每个item指定一个格式符
格式符:
%c: 显示字符和ASCII码
%d,%i: 显示十进制整数
%e, %E: 科学记数法数值显示
%f: 显示为浮点数
%g, %G: 以科学记数法或浮点数显示数值
%s: 显示字符串
%u: 无符号整数
%%:显示%自身
修饰符:
#[.#]: 第一个#控制显示宽度;第二个#标识小数点后的精度
%3.1f
-: 左对齐
+:显示数值符号
awk -F: '{printf "username:%-15s,uid:%-d\n",$1,$3}' /etc/passwd
操作符:
算术操作符:x+y, x-y, x*y, x/y, x^y, x%y, -x, +x
字符串操作符:没有符号的操作符,字符串连接
赋值操作符:=, +=, -=, *=, /=, %=, ^=, ++, --
比较操作符:>, >=, <=, <, !=, ==
模式匹配符:~,!~
逻辑操作符:&&,||,!
函数调用:function_name(argu1, argu2, ...)
条件表达式:
selector?if-true-expression:if-false-expression
事例: awk -F: '{$3>=1000?usertype="common user":usertype="sysuser"printf "%15s:%-s\n",$1,usertype}' /etc/passwd
PATTERN
empty: 空模式,匹配每一行
[!]/regular expression/: 仅处理被匹配到的行
关系表达式:结果为“真”或“假”,只有“真”才会被处理
“真”:结果为非0,非空字符串
line ranges:
awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
BEGIN|END模式:
BEGIN{}: 在开始处理文本之前执行一次
END{}: 在文本处理完成之后执行一次
常用ACTION
Expressions
控制语句:if, while等
组合语句
输入语句
输出语句
控制语句
if(condition) {statments}
if(condition) {statments} else {statments}
对awk取得的整行或某个字段做条件判断
awk -F: '{if($3>=1000) {printf "common user: %s\n",$1} else {printf "sysuser: %s\n",$1}}' /etc/passwd
awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
awk '{if(NF>5) print $0}' /etc/fstab
df -h | awk -F% '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}'
for(expr1;expr2;expr3) {statments}
awk '/^[[:space:]]*linux16/{for(i=1;i<=Nf;i++) {print $i,length($i)}}' /etc/grub2.cfg
特殊用法:遍历数组中的元素
for(var in array) {statments}
while(condition) {statments}
对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg
awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg
do {statments} while(condition)
至少执行一次循环体
break
continue
next: 提前结束对本行的处理而进入下一行
awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
delete array[index]
delete array
exit
数组:
关联数组:array[index-expression]
index-expression:
可使用任意字符串;用“”
如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”
若要判断数组中是否存在某元素,要使用“index in array”格式进行
若要遍历数组中每个元素,要使用for循环
for(var in array) {statments}
var表示array的索引
awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
akw '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab
统计指定文件中每个单词出现的次数
awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
函数
内置函数
数值处理
rand(): 返回0-1之间的随机数
字符串处理
length(s): 返回指定字符串长度
awk -F: ‘{print $1":"$3}' /etc/passwd
awk -v FS=: ‘{print $1FS$3}' /etc/passwd
awk -v var1="hello" 'BEGIN{print var1}'
awk 'BEGIN{i=0;print ++i,i}' 1 1
awk 'BEGIN{i=0;print i++,i}' 0 1
awk -F: '$0 ~ /root/{print $0}' /etc/passwd
netstat -ant | awk '/^tcp/{state[$NF]++}END{for(a in state){print a,state[a]}}'
awk '/^[0-9]/{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log
awk '{for(i=1;i<=NF;i++){word[$i]++}}END{for(j in word){print j,word[j]}}' /etc/rc.sysinit
awk 'BEGIN{srand();for(i=0;i<10;i++)print int(rand()*100)}'
awk '/Failed password/{ip[$(NF-3)]++}END{for(i in ip){if(ip[i]>=3)system("iptables -A INPUT -s " i " -j REJECT") }}' /var/log/secure