LinuxShell之字符截取和替换命令


一 cut提取命令

  cut命令的默认分割符是制表符,也就是"tab"键

 

 

 二 printf格式化输出

 

 

 三 awk编程

   1 awk基本使用

 

 awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
 [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value

 

[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
练习数据:student.txt
[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分的行.如果判断成立,则打印第六列(学院名)
示例1:查看平均成绩大于等于87分的学员是谁

 加入了条件之后,只有条件成立动作才会执行,如果条件不满足,则动作则不运行.通过这个实验,可以发现,虽然awk是列提取命令,但是也要按行来读入的.这个命令的执行过程是这样的:

①如果有BEGIN条件,则先执行BEGIN定义的动作;

②如果没有BEGIN条件,则读入第一行,把第一行的数据一次赋予$0,$1,$2等变量.其中$0代表此行的整体数据,$1代表第一字段,$2代表第二字段.

③依据条件类型判断动作是否执行.如果条件符合,则执行动作,否则读入下一行数据.如果没有条件,则每行都执行动作.

④读入下一行数据,重复执行上述步骤.

[root@hang ~]# awk '$2 ~ /Sc/ {printf $6 "\n"}' student.txt 
85.66
示例:查看Sc用户的平均成绩

2.4 正则表达式

若想让awk识别字符串,必须使用"//"包含,例如:

[root@hang ~]# awk '/LiMing/ {print}' student.txt 
1       LiMing  82      95      86      87.66
打印用户LiMing的信息
[root@hang ~]# df -h |awk '/sda[0-9]/ {print $1 "\t" $5 "\t"}'
/dev/sda2       20%
/dev/sda1       22%
用df命令查看分区使用情况时,若只想查看真正的系统分区的使用情况,而不像查看光盘和临时分区的使用情况

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值)}
查询可以登录的用户的用户名和UID,并查询行号即及字段数
[root@hang ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $1=="sshd" {print $1 "\t" $3 "\t 行号:" NR "\t 字段数:" NF "\n"}'
sshd    74       行号:32         字段数:7
查询sshd这个伪用户的相关信息

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
统计php成绩总分

在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!
方法1:若Linux成绩大于90,就是一个好男人
[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:若Linux成绩大于90,就是一个好男人

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
使用函数打印student.txt的学员姓名和平均成绩

2.8 awk中调用脚本

 当程序是多行时,使用外部脚本是合适的.首先在外部文件中写好脚本,然后使用awk的-f选项,使其读入脚本并执行.

BEGIN {FS=":"} {print $1 "\t" $3}
pass.awk
[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
调用pass.awk脚本

四 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
同时执行多个sed操作

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM