sed 一般用于对文本内容做替换
awk 一般用于对文本内容进行统计,按需要格式输出
sed
sed的工作方式
1、将文件以行为标准读入到内(模式空间)
2、使用sed的每个脚本对该行进行操作
3、处理完后输出该行
替换命令 s
-e 执行多个替换命令
-i 保存替换
-r 支持拓展正则表达式
#默认情况下只替换一行中匹配的第一次的字符
sed's/old/new/'filename
sed's/old/new/'filename1 filename2
sed -e 's/old/new/' -e 's/old/new/' filename
sed -e 's/old/new/' -e 's/old/new/' filename1 filename2
sed 's/old/new/' ; 's/old/new/' filename1 filename2
sed -i 's/old/new/' 's/old/new/' filename
sed 's/正则表达式/new/' filename
sed -r 's/拓展正则表达式/new/' filename
sed's/old/new/标志位'filename
#在同一行替换所有符合条件的字符
sed 's/20/200/g' date
#在一行中替换指定的匹配到的次数(2为替换匹配的第二次)
sed 's/20/202/2' date
#p打印模式空间的内容
#对匹配成功的行打印一次(会输出两次)
sed 's/20/202/p' date
#-n对内容不做输出处理,又用户自己选择是否输出
sed -n 's/20/202/' date #(无任何输出)
sed -n 's/20/202/p' date #(输出处理过的行)
#只处理指定行
sed '/正则/s/old/new/' filename
sed '/正则/s/old/new/g' filename
sed '/正则/s/old/new/2' filename
sed '/2s/old/new/' filename
sed '/2s/old/new/g' filename
sed '/$s/old/new/' filename # $ 表示最后一行
#替换2-5行
sed '/2,5s/old/new/' filename
#正则和番号混用 sed '/正则/,行号s/old/new/标志位' filename
sed '/^20/,$s/old/new/' filename
#寻址后在一行中进行多条命令
sed '/正则/{命令1;命令2}' filename
sed -n '/^12/{s/20/111/;s/CST/000/}' date
sed -n '/^12/{s/20/111/;s/CST/000/p}' date
#删除(删除模式空间累的文件,d后面的命令不会再被执行,直接开始新的一行)
# sed '/s2/d' filename
sed '/^12/d' date
sed '/^12/!d' date #删除非12开头的行
sed '2d' date
sed '2,5d' date
#插入 i (在匹配行上面插入)
sed '/^12/i 172.6.2.1 ' date
#追加 a (在匹配行后面追加内容)
sed '/^12/a hhahah' date
sed 4a\123456789 date
#读取 r 读取匹配内容到文件
sed '/^12/r a.txt' date #读取a.txt的内容追加到date中以12开头的行后
#更改 c (把匹配行直接改写为指定内容)
sed '/^12/c 172.6.2.1 ' date
# n跳过本行,处理下一行
# p 打印匹配的行
sed '/^120/P' date
sed -n '/^12/p' date
q退出
sed -n '10q' date
sed引用变量
name=li
#定义一个变量,且给变量赋值
sed -i "s/jie/$name/" myfile
#把匹配jie的字符替换成变量的值
sed的多行模式
N 将下一行追加入到模式空间
D 删除模式空间中的第一个字符到第一个换行符
P 打印模式空间中的第一个字符到第一个换行符
sed 'N;s/\n//;s/hello bash/hallo sed\n/;P;D' feilname
#s/\n// 换行符替换为空
#s/hello bash/hallo sed\n/ hello bash 替换为hallo sed\n P 输出第一个字符到第一个换行符
#D 删除前面处理并打印的,开始进行下一行处理,回到N开始处理
sed 'N;N;s/\n//;s/hello bash/hallo sed\n/;P;D' feilname
#N;N; 读取三方到模式空间进行处理
cat > test.txt << EOF
sed的保持空间(进行多行处理的一种模式,可以存储内容)
awk
输入数据前例程BEGIN{} ---- 变量定义
BEGIN 模式:是指 awk 将在读取任何输入行之前立即执行BEGIN 中指定的动作。
END 模式:是指 awk 将在它正式退出前执行 END中指定的动作。
主输入循环{}
所有文件读取完成例程{} -----数据汇总
字段的应用和分离
每行称为awkd记录
使用空格、制表符分隔开的单词称为字段
可以自己指定分隔符
$1 $2
3......
3 ......
3......n 表示分隔的每一个字段
awk '{print $1,$3}' filename
使用 -F指定分隔符(分隔符可以使用正则表达式)
#读取指定的匹配行
awk '/CST$/ {print $1,$2,$3}' filename
#使用单引号分隔
awk -F"'"'{print $1,$2,$3}' filename
#分隔符使用正则表达式 $0 表示整行
awk -F'12.''{print $0}' filename
#输出时显示行号
awk -F '19.' '{print X++ $2}' filename
awk的表达式
赋值
# =
var1="name" var2= "hello" "word" (多个字符号串会合并) var3 = $1 (分隔开的第一个字段)
算数
# ++
# --
# +=
# -=
# *=
# /=
# %=(取余)
# ^=(乘方)
# 系统变量
# FS OFS (FS 输入的字段分隔符 OFS输出的分隔字段符)
head -5 /etc/passwd | awk -F ":" '{print $1,$2}'
head -5 /etc/passwd | awk 'BEGIN{FS=":"}{print $1}'
head -5 /etc/passwd | awk 'BEGIN{FS=":";OFS="--"}{print $1,$2}' #OFS="--" 指定输出的连接符为--
# root--x
# bin--x
# daemon--x
# adm--x
# lp--x
# RS 记录分隔符 默认为换行符 \n 指定换行符
head -5 /etc/passwd | awk 'BEGIN{RS=":"}{print $0}' # 指定换行符为:
# NR FNR 表示行数
# NF 字段的数量,表示分隔出来了多少个字段;最后一个字段的内容可以用$FN取出
head -5 /etc/passwd | awk 'BEGIN{FS=":";OFS="--"}{print NF,$NF}'
关系操作符
< > <= >= == != ~(匹配) !~
布尔操作符
&& 与 || 或 ! 非
控制流
#判断
# if 表达式为真返回 1 为假返回 0
if(表达式)
awk语句1
[else
{awk语句2
awk语句3
}
]
awk '{if($2>=80) print $1)}' filename
awk '{if($2>=80) {print $1;print $2}}' filename
# 循环
while(表达式)
awk语句
do{
awk语句
}while(表达式)
for(初始值;循环判断条件;累加)
awk语句
awk '{for(i=2;c<NF;i++) print i}' filename
awk '{for(i=2;c<NF;i++) s=s+$i;print s}'
awk '{for(i=2;c<NF;i++) s+=$i; print s/NF-1)}'
awk '{s=0; for(i=2;c<NF;i++) s=s+$i}'
# break
# continue
awk的end模式,在文件读取完之后才执行end后的表达式
# 数组(key value)
# 定义
# 名称[下标]=值
awk '{ s=0;for(i=2;i<=NF;i++)s+=$i;avg[$1]=s/(nf-1)}END{for(user in avg) print user,avg[user]}' filename
awk '{ s=0;for(i=2;i<=NF;i++)s+=$i;avg[$1]=s/(nf-1)}END{for(user in avg) sum+=avg[user];print s/NR}' filename
# 遍历
# for(变量in数组名称)
# 删除
# delete 数组名 delete数组[下标]
# 命令行参数数组
ARGC变量(awk后面带的参数的数量个数)
ARGV数组(awk后面带的参数的每一个的具体内容)
#读取
名称[下标]
awk加载脚本文件
awk -f script filename
{
sum = 0
for( column = 2 ; column <= NF; column++ )
sum += $column
average[$1] = sum / ( NF - 1 )
if ( average[$1] >= 80 )
letter = "s"
else if ( average[$1] >= 70 )
letter = "A"
else if ( average[$1] >= 60 )
letter = "B"
else
letter = "C"
print $1,average[$1],letter
letter_all[letter]++ #统计各个letter的次数
}
END{
for ( user in average )
sum_all += average[user]
avg_all = sum_all / NF
for ( user in average )
if ( average[user] > avg_all )
above++
else
below++
print "ab",above
print "be",below
}
awk的函数
算数函数
sin()
cos()
int()
rand()
srang()
字符串函数
gsub(r,s,t)
index(s,t)
length(s)
match(s,r)
sqlit(s,a,sep)
sub(r,s,t)
substr(s,p,n)
自定义函数