文件处理工具sed和awk
sed的两种用法:1、命令行模式 2、脚本模式
选项: -e : 进行多项编辑,即对输入行应用多条sed命令时使用
-n : 取消默认的输
-f : 指定sed的脚本名
-r : 使用扩展正则表达式
-i : 修改源文件
常用命令及用法:
sed -n ‘p’ a.txt p:打印符合条件的行
sed -n ‘1p’ a.txt 打印第一行
sed -n ‘1,5p’ a.txt 打印1到5行
$: 最后一行
使用正则:sed -n ‘/ /command’ a.txt
命令:r 、w
r:从文件中读取输入行 w:将所选的行写入文件
sed ‘5r /etc/hosts’ 1.txt 将/etc/hosts 文件输入到1.txt文件的第五行下
sed ‘5w ./a.txt’ 1.txt 将1.txt文件中的第五行输入到a.txt文件中
i:行前插入 a、行后插入
c:替换
sed -n ‘1,5chello world’ 1.txt 1到5行替换成hello world
!:取反,对所选行以外的所有行应用命令,放到行数之后
sed -n ‘1!p’ 1.txt 打印出了第一行以外的行
s:用一个字符串替换另一个
g:在行内进行全局替换
&:保存查找串以便在替换中引用
=:打印行号
sed -n ‘s/root/#&/p’ a.txt 此处&代表root,保留前面的root
sed -n ‘/^root/=’ 1.txt 以root开头的行的行号
awk基本应用
$0:表示当前处理行
$1,$2, 3... 3... 3...n:awk中用该顺序形式表示files中每行以间隔符号分割的各列的不同字段
NF:表示当前记录的列数
$NF:最后一列
$(NF-1):倒数第二列
NR:行号
FILENAME 文件名
“\t” 制表符
“\n” 换行符
“” 打印字符串
FS:定义间隔符
OFS:定义输出字段间隔符
RS:输入记录分隔符,默认换行
ORS:输出记录分隔符,默认换行
print:打印函数 printf:取消换行打印
awk -F: ‘NR==2{print 1 , 1, 1,(NF-1)}’ 1.txt 打印1.txt文件第二行中以:为分隔符的第一列和倒数第二列
定义变量:
awk -v NUM=3 -F: ‘{ print NUM }’ /etc/passwd
awk中调用定义的变量不需要加$
关键字:
BEGIN:表示在程序开始前执行
END:表示所有文件处理完后执行
打印/etc/passwd里的用户名、家目录及登录shell:
u_name h_dir shell
***************************
***************************
使用:awk 'BEGIN{FS=":";print "u_name\th_dir\tshell\n**************************************" } {print $1"\t"$(NF-1)"\t"$NF} END{print "*****************************************"}'
计算1~10的和
for ((i=1;i<=10;i+=2));do echo $i;done|awk -v sum=0 '{sum+=$0};END{print sum}'
awk打印1~5
awk 'BEGIN{for(i=1;i<=5;i++) print i}'
正则表达式:
打印以root开头或者以lp开头的行
awk -F: '/^root/ || /^lp/{print $0}' passwd
awk -F: '/^root/;/^lp/{print $0}' passwd
打印本机的IP地址、广播地址、mask码
ifconfig eth0|awk 'NR==2{print $0}'| awk -F'[ :]+' '{print $4 ORS $6 ORS $8}'
10.1.1.1
10.1.1.255
255.255.255.0
打印出系统中普通用户的UID和用户名
awk -F: 'BEGIN{print "UID\tUSERNAME"} {if($3>=500 && $3 !=65534 ) {print $3"\t"$1} }' /etc/passwd
UID USERNAME
500 gaoxing
501 code1
502 code2
503 code3
504 pos1
流程控制语句
用法:
awk -F: '{ if($3>=500 && $3 != 65534) {print $1"是普通用户"} else {print $1"不是普通用户"}}' passwd
打印出管理员用户、系统用户、普通用户个数
awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print "管理员个数: "i; print "普通用个数: "k; print "系统用户: "j}' /etc/passwd
循环语句
用法:
while
打印1~10行
awk 'BEGIN{i=1; while(i<=10){print i; i++}}'
for
awk 'BEGIN{for(i=1; i<=10; i++){print i}}'
不支持until循环
嵌套循环:
awk 'BEGIN{for(y=1; y<=5; y++){for(x=1; x<=y; x++)printf x; print}}
1
12
123
1234
12345
尝试用三种方法打印99口诀表
awk 'BEGIN{for(y=1;y<=9;y++) {for(x=1;x<=y;x++)printf x"*"y"="x*y"\t";print} }'
awk 'BEGIN{i=1;while(i<=9){for(j=1;j<=i;j++){printf i"*"j"="i*j"\t"}print;i++}}'
awk 'BEGIN{for(y=1;y<=9;y++) {x=1;while(x<=y) {printf x"*"y"="x*y"\t" ;x++}print}}'
算数运算
用法
统计/etc/passwd 中各种类型shell的数量 (使用关联数组)
awk -F: '{shells[$NF]++};END{for(i in shells)print i,shells[i]}}' /etc/passwd