一 cut提取命令
cut命令的默认分割符是制表符,也就是"tab"键
二 printf格式化输出
三 awk编程
1 awk基本使用

[root@hang ~]# cat student.txt ID Name PHP Linux MySQL Average 1 LiMing 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Tg 99 83 93 91.66

[root@hang ~]# awk '{printf $2 "\t" $6 "\n"}' student.txt Name Average LiMing 87.66 Sc 85.66 Tg 91.66
2 awk的条件
2.1 BEGIN
BEGIN是awk的保留字,是一种特殊的条件类型. BEGIN的执行时机是"awk程序一开始时,尚未读取任何数据之前执行".一旦BEGIN后的动作执行一次,当awk开始从文件中读入数据,BEGIN的条件就不在成立,所以BEGIN定义的动作只能被执行一次.

[root@hang ~]# awk 'BEGIN{printf "This is a transcript \n"} {printf $2 "\t" $6 "\n"}' student.txt This is a transcript Name Average LiMing 87.66 Sc 85.66 Tg 91.66 #awk命令只要检测不到完整地单引号就不会执行,所以这个命令的换行不用加入"\"就是一行命令 #这里定义了两个动作 #第一个动作使用BEGIN条件,所以会在读入文件数据前打印"这是一张成绩单"(只会执行一次) #第二个动作会打印文件的第二个字段和第六个字段
2.2 END
END也是awk保留字,不过刚好和BEGIN相反.END是在awk程序处理完所有数据,即将结束时执行.END后的动作只在程序结束时执行一次

[root@hang ~]# awk 'END{printf "The End \n"} {printf $2 "\t" $6 "\n"}' student.txt Name Average LiMing 87.66 Sc 85.66 Tg 91.66 The End
2.3 关系运算符

[root@hang ~]# cat student.txt |grep -v Name | awk '$6 >= 87 {printf $2 "\n"}' LiMing Tg #使用cat输出文件内容,用grep取不包含"Name"的行 #判断第六个字段(平均成绩)大于等于87分的行.如果判断成立,则打印第六列(学院名)
加入了条件之后,只有条件成立动作才会执行,如果条件不满足,则动作则不运行.通过这个实验,可以发现,虽然awk是列提取命令,但是也要按行来读入的.这个命令的执行过程是这样的:
①如果有BEGIN条件,则先执行BEGIN定义的动作;
②如果没有BEGIN条件,则读入第一行,把第一行的数据一次赋予$0,$1,$2等变量.其中$0代表此行的整体数据,$1代表第一字段,$2代表第二字段.
③依据条件类型判断动作是否执行.如果条件符合,则执行动作,否则读入下一行数据.如果没有条件,则每行都执行动作.
④读入下一行数据,重复执行上述步骤.

[root@hang ~]# awk '$2 ~ /Sc/ {printf $6 "\n"}' student.txt 85.66
2.4 正则表达式
若想让awk识别字符串,必须使用"//"包含,例如:

[root@hang ~]# awk '/LiMing/ {print}' student.txt 1 LiMing 82 95 86 87.66

[root@hang ~]# df -h |awk '/sda[0-9]/ {print $1 "\t" $5 "\t"}' /dev/sda2 20% /dev/sda1 22%
2.5 awk内置变量

[root@hang ~]# cat /etc/passwd|grep "/bin/bash" | awk ' BEGIN {FS=":"} {printf $1 "\t" $3 "\t 行号:" NR "\t 字段数:" NF "\n"}' root 0 行号:1 字段数:7 #开始执行{分隔符是":"}{输出第一字段和第三字段 输出行号(NR值) ziduans(NF值)}

[root@hang ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $1=="sshd" {print $1 "\t" $3 "\t 行号:" NR "\t 字段数:" NF "\n"}' sshd 74 行号:32 字段数:7
2.6 awk流程控制

[root@hang ~]# awk 'NR==2{php1=$3} NR==3{php2=$3} NR==4{php3=$3;total=php1+php2+php3;print "total php is:" total}' student.txt total php is:255
在awk编程中,因为命令的语句过长,在输入格式时需要注意一下内容:
①多个条件{动作}可以用空格分隔,也可以用回车分隔.
②在一个动作中,如果需要执行多个命令,需要用";"分隔,或用回车分隔.
③在awk中,变量的赋值与调用都不需要加入"$"符.
④条件中判断两个值是否相同,请使用"==",以便和变量赋值进行区分.

[root@hang ~]# awk '{if (NR>=2) {if ($4>=90) print $2 " is a good man!\n"}}' student.txt LiMing is a good man! Sc is a good man!

[root@hang ~]# awk 'NR>=2 {test=$4} test>=90 {print $2 " is a good man!\n"}' student.txt LiMing is a good man! Sc is a good man!
2.7 awk函数
awk编程允许在编程时使用函数,awk函数的定义方法如下:

[root@hang ~]# awk 'function test(a,b) {printf a "\t" b "\n"} {test($2,$6)}' student.txt Name Average LiMing 87.66 Sc 85.66 Tg 91.66
2.8 awk中调用脚本
当程序是多行时,使用外部脚本是合适的.首先在外部文件中写好脚本,然后使用awk的-f选项,使其读入脚本并执行.

BEGIN {FS=":"} {print $1 "\t" $3}

[root@hang ~]# awk -f pass.awk /etc/passwd root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13 ftp 14 nobody 99 dbus 81 usbmuxd 113 rpc 32 rtkit 499 avahi-autoipd 170 vcsa 69 abrt 173 rpcuser 29 nfsnobody 65534 haldaemon 68 ntp 38 apache 48 saslauth 498 postfix 89 gdm 42 pulse 497 sshd 74 tcpdump 72
四 sed命令
sed命令主要是用来将数据进行选取,替换,删除,新增的命令
注意:sed所做的修改并不会直接改变文件的内容,而是把修改结果只显示到屏幕上,除非用"-i"才会直接修改文件
行数数据操作

[root@hang ~]# sed -n '2p' student.txt 1 LiMing 82

#删除第二行到第四行数据 [root@hang ~]# sed '2,4d' student.txt ID Name PHP Linux MySQL Average #但是本身文件并没有修改,除非使用"-i" [root@hang ~]# cat student.txt ID Name PHP Linux MySQL Average 1 LiMing 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Tg 99 83 93 91.66 [root@hang ~]

[root@hang ~]# sed -n '2i hello \ world' student.txt hello world #-n 只查看sed命令操作的数据,而不是查看所有数据

[root@hang ~]# sed '2i hello \ > world' student.txt ID Name PHP Linux MySQL Average hello world 1 LiMing 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Tg 99 83 93 91.66

[root@hang ~]# cat aaa.txt ID Name PHP Linux MySQL Average 2 Sc 74 96 87 85.66 3 Tg 99 83 93 91.66 [root@hang ~]# sed -i '2c No such person' aaa.txt [root@hang ~]# cat aaa.txt ID Name PHP Linux MySQL Average No such person 3 Tg 99 83 93 91.66 [root@hang ~]#
字符串替换
"c"动作是进行整行替换的,若仅仅想替换行中的部分数据,就要使用"s"动作了,s动作格式是:
sed 's/旧字符串/新字符串/g' 文件名

[root@hang ~]# cat aaa.txt ID Name PHP Linux MySQL Average 1 LiMing 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Tg 99 83 93 91.66 #这里使用正则表达式,"^"代表行首 [root@hang ~]# sed -i '4s/^/#/g' aaa.txt [root@hang ~]# cat aaa.txt ID Name PHP Linux MySQL Average 1 LiMing 82 95 86 87.66 2 Sc 74 96 87 85.66 #3 Tg 99 83 93 91.66

[root@hang ~]# sed -e 's/LiMing//g;s/Tg//g' aaa.txt ID Name PHP Linux MySQL Average 1 82 95 86 87.66 2 Sc 74 96 87 85.66 #3 99 83 93 91.66 #-e选项可以同时执行多个sed动作,多个动作之间要用";"号或回车分隔 [root@hang ~]# sed -e 's/LiMing//g > s/Tg//g' student.txt ID Name PHP Linux MySQL Average 1 82 95 86 87.66 2 Sc 74 96 87 85.66 3 99 83 93 91.66