Linux基础学习之Shell编程——字符截取命令相关——printf、cut、awk、sed

 

一、字符截取命令之cut命令

1、字符截取命令有哪些?

grep  cut    printf(严格来说不算)   awk   sed  命令

2、grep 是在文件当中提取符合条件的行

      cut  是在文件当中提取符合条件的列

3、cut命令:

[root@localhost ~]# cut 【选项】文件名

选项:

  -f  列号    :提取第几列

  -d  分隔符:按照指定分隔符分隔列

注意:测试文档如下

[root@localhost sh]# vim student.txt

ID      Name    gender  Mark
1       Liming  M       86
2       Sc      M       90
3       Gao     M       83
~                    

注意 空白不是空格,而是制表符

[root@localhost sh]# cut -f 2 student.txt 
Name
Liming
Sc
Gao
[root@localhost sh]# cut -f 2,3 student.txt 
Name	gender
Liming	M
Sc	M
Gao	M
[root@localhost sh]# 

示例2、提取/etc/passwd 文件中内容,用于练习-d选项

Gao	M
[root@localhost sh]# vim /etc/passwd

daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rtkit:x:499:499:RealtimeKit:/proc:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
[root@localhost sh]# cut -d ":" -f 1,3 /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
zhouxueli:500
sc:501
bimm:502
cangls:503
st:504
lamp:505
[root@localhost sh]# 

4、字符截取命令在编程中有什么作用呢?

如果想要批量添加一定量的用户,但是发现普通用户不合要求,想删除普通用户,

所以可以根据截取命令,把用户名提取出来,之后根据用户名删除,

所以利用cut命令将用户名批量提取,根据root取反,提取普通用户,

编写脚本,利用循环,把这些用户删除

等等类似这种情形可用

5、cut命令的局限[root@localhost ~]# df -h | cut -d " " -f 1,3

[root@localhost sh]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  7.8G  8.5G  48% /
tmpfs                 931M   76K  931M   1% /dev/shm
/dev/sda1             477M   41M  411M   9% /boot
/dev/sdb1             2.0G  3.1M  1.9G   1% /disk1
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
/dev/sr0              1.1G  1.1G     0 100% /media/Ubuntu 14.04.5 LTS amd64
[root@localhost sh]#  df -h | grep "sda5"
[root@localhost sh]# df -h | grep "sdb5"
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
[root@localhost sh]# df -h | grep "sdb5" | cut -f 5
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
[root@localhost sh]# df -h | grep "sdb5" | cut -d "  " -f 5
cut: 分界符必须是单个字符
请尝试执行"cut --help"来获取更多信息。
[root@localhost sh]# 
[root@localhost sh]# df -h | grep "sdb5" | cut -d " " -f 5

[root@localhost sh]# 

cut 命令不能将空格作为分隔符进行分隔,因为cut命令对空格的识别率较低

awk命令可以通过较为复杂的匹配规则进行处理该问题

建议cut命令能处理的尽量使用cut,而不是awk命令,awk 通常被称为awk编程,awk有很多其他的功能

二、printf 命令:

1、printf  命令严格来说不是字符截取命令,但是通常和cut命令放在一起用

,作为标准输出;

2、printf 命令:

printf  '输出类型输出格式' 输出内容

输出类型:

  %ns:   输出字符串。n是数字指代输出几个字符

  %ni :    输出整数。n是数字指代输出几个数字

  %m.nf : 输出浮点数。m和n是数字,指代输出的整数位数和小数位数。如%8.2f代表共输出8位数,其中2位是小数,6位是整数。

输出格式:

\a  :输出警告声音

\b:输出退格键,也就是Backspace键

\f :清除屏幕

\n :换行

 \r :回车,也就是Enter键

 \t :水平输出退格键,也就是Tab键

\v :垂直输出退格键,也就是Tab键

[root@localhost sh]# printf %s 1 2 3 4 5 6
123456[root@localhost sh]# printf %s %s %s 1 2 3 4 5 6
%s%s123456[root@localhost sh]# printf '%s %s %s' 1 2 3 4 5 6
1 2 34 5 6[root@localhost sh]# printf '%s %s %s \n' 1 2 3 4 5 6
1 2 3 
4 5 6 
#如下,'%s %s %s\n'表示将内容按照后面的内容按照%s的个数为一组,然后换行,在此即表示三个一组,然后换行
[root@localhost sh]# printf  1 2 3 4 5 6
1 2 3
4 5 6
[root@localhost sh]# 
[root@localhost sh]# printf '%s' student.txt 
student.txt[root@localhost sh]# printf '%s' $(cat student.txt )
IDNamegenderMark1LimingM862ScM903GaoM83[root@localhost sh]# 

学习printf命令的原因是:

awk编程中无法直接调用系统中的cat 等命令,内容输出需要用到printf 协助,所以在此学习

如上:

》printf '%s' $(cat student.txt)

#不调整输出格式

》printf '%s\t %s\t %s\t %s\t %s\t %s\t \n' $(cat student.txt)

#调整格式输出

[root@localhost sh]# cat student.txt 
ID	Name	gender	Mark
1	Liming	M	86
2	Sc	M	90
3	Gao	M	83

[root@localhost sh]# printf '%s\t %s\t %s\t %s\t %s\t %s\t \n' $(cat student.txt)
ID	 Name	 gender	 Mark	 1	 Liming	 
M	 86	 2	 Sc	 M	 90	 
3	 Gao	 M	 83	

3、在awk明星的输出中支持print 和printf命令

》print:print会在每个输出之后自动加入一个换行符(Linux默认没有print命令)

》printf:printf是标准格式输出命令,并不会自动加入换行符,如果需要换行,需要手工加入换行符;

三、awk命令:

1、cut命令只能使用制表符 冒号 逗号或者其他的,但不能用空格

   awk命令 可以实现cut命令所有的功能,awk命令经常被作为编程语言认识

2、awk命令格式:

# awk ‘条件1{动作1} 条件2{动作2} ...’  文件名

条件(Patterm):

 一般使用关系表达式作为条件

  x>10   判断变量x是否大于10

  x>=10   大于等于

 x<=10    小于等于

动作(Action):

      格式化输出    注意:格式调整建议使用双引号括起来,而不是单引号

      流程控制语句

3、简单示例:

示例文档:

[root@localhost sh]# vim student1.txt 

ID      Name    PHP     Linux   Mysql   Average
1       Liming  82      95      86      87.66
2       Sc      74      96      87      85.66
3       Gao     99      83      93      81.66
~                                                                                                  

示例1、注意:格式调整建议使用双引号括起来,而不是单引号

[root@localhost sh]# awk '{printf $2 "\t" $6 "\n"}' student1.txt 
Name	Average
Liming	87.66
Sc	85.66
Gao	81.66
[root@localhost sh]# 

示例2:、空格作为分隔符时,awk的执行(cut命令无法将空格作为分隔符)

[root@localhost sh]# df -h | awk '{print $1 "\t" $5 "\t" $6}' 
Filesystem	Use%	Mounted
/dev/mapper/VolGroup-lv_root		
18G	/	
tmpfs	1%	/dev/shm
/dev/sda1	9%	/boot
/dev/sdb1	1%	/disk1
/dev/sdb5	1%	/disk5
/dev/sr0	100%	/media/Ubuntu
[root@localhost sh]# 

注:如上awk命令中里面是有print 命令的,但Linux中没有print命令

示例3、

[root@localhost sh]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  7.8G  8.5G  48% /
tmpfs                 931M   76K  931M   1% /dev/shm
/dev/sda1             477M   41M  411M   9% /boot
/dev/sdb1             2.0G  3.1M  1.9G   1% /disk1
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
/dev/sr0              1.1G  1.1G     0 100% /media/Ubuntu 14.04.5 LTS amd64
[root@localhost sh]# 
[root@localhost sh]# df -h | grep sdb5
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
[root@localhost sh]# df -h | grep sdb5 | awk '{print $5}'
1%
[root@localhost sh]# df -h | grep sdb5 | awk '{print $5}' | cut -d "%" -f1
1
[root@localhost sh]# df -h | grep sdb5 | awk '{print $5}' | cut -d "%" -f 1
1
[root@localhost sh]# 

4、BEGIN命令

# awk 'BEGIN {printf "This is a transcript \n"}   {printf $2 "\t" $6 "\n"}' student1.txt

#如上表示在执行下面一行时,会先执行BEGIN后面跟着的第一个动作

[root@localhost sh]# awk 'BEGIN{print "test !!"} {print $2 "\t" $5}' student1.txt 
test !!
Name	Mysql
Liming	86
Sc	87
Gao	93
[root@localhost sh]# 
[root@localhost sh]# awk '{FS=":"} {print $1 "\t" $3}' /etc/passwd
root:x:0:0:root:/root:/bin/bash	
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
zhouxueli	500
sc	501
bimm	502
cangls	503
st	504
lamp	505
[root@localhost sh]# 

注意BEGIN的存在和执行结果第一行的区别

[root@localhost sh]# awk 'BEGIN{FS=":"} {print $1 "\t" $3}' /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
zhouxueli	500
sc	501
bimm	502
cangls	503
st	504
lamp	505
[root@localhost sh]# 

5、END命令

# awk 'END{printf "The End \n"} {printf $2 "\t" $6 "\n"}' student1.txt

#如上表示等待{printf $2 "\t" $6 "\n"}' student1.txt 执行完成后,再执行END 紧挨的动作

[root@localhost sh]# awk 'END{printf "The End \n"} {printf $2 "\t" $6 "\n"}' student1.txt 
Name	Average
Liming	87.66
Sc	85.66
Gao	81.66
The End 
[root@localhost sh]# 

6、FS内置变量  FS 用于定义分隔符的

# cat /etc/passwd | grep "/bin/bash" | \

awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'

#注意如上内容表示查看文件passwd文件内的内容,把里面带如下字符串/bin/bash 

的行 提取出来,然后将其中的第一列 第三列打印出来

[root@localhost sh]# cat /etc/passwd | grep "/bin/bash" | \
> awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'
root	0
zhouxueli	500
sc	501
bimm	502
cangls	503
st	504
lamp	505
[root@localhost sh]# 
[root@localhost sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# cat student1.txt | grep -v Name | awk '$6 >=87 {printf $2 "\n"}'
Liming

awk编程可以通过shell编程进行处理,awk只用于处理字符串的截取

四、sed命令

1、grep 用于行截取,cut 和awk 用于列截取,而sed实际是用于流内容的编辑

2、sed 是一种几乎包括在所有UNIX平台(包括Linux)的轻量级流编辑器。

    sed 主要是用来将数据进行选取、替换、删除、新增的命令。

vi 只能修改文件中的内容,但是vi不能把某个命令的某个执行结果直接修改,必须要把

执行结果输入到文件中,才能修改。但是sed命令可以直接通过管道操作符将命令的

执行结果进行直接的选取、替换、删除、新增的编辑。

3、sed命令的格式:

[root@localhost ~]# sed 【选项】‘[动作]'  文件名

选项:

 -n   :一般sed命令会把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕

 -e :允许对输入数据应用多条sed命令编辑

  -i  :用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出

动作:

a\  :追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用“\”代表数据未完成

c\  :行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结。

i\  :插入,在当前行前面插入一行或多行。插入多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。

d  :删除,删除指定的行。

p : 打印,输出指定的行。

s   :字串替换,用一个字符串替换另外一个字符串。格式为“航范围s/旧字串/新字串/g”(和vim 中替换格式类似)。

示例1:行数据操作

[root@localhost ~]# sed '2p' student1.txt

#查看文件的第二行

[root@localhost ~]# sed -n  '2p' student1.txt

[root@localhost sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# sed '2p' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# sed -n '2p' student1.txt 
1	Liming	82	95	86	87.66
[root@localhost sh]# 

示例2、删除行数据操作

[root@localhost sh]# sed '2,4d' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
[root@localhost sh]# sed '2,3d' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
3	Gao	99	83	93	81.66
[root@localhost sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# 

 示例3、

[root@localhost ~]# sed '2a hello' student1.txt

#在第二行后追加hello

[root@localhost ~]# sed '2i hello \

world ' student1.txt

#在第二行前插入两行数据

[root@localhost sh]# sed '2i hello' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
hello
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# sed '2i gao \
> world ' student1.txt
ID	Name	PHP	Linux	Mysql	Average
gao 
world 
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# 

 示例4、

#sed '2c No such person ' student1.txt

#数据替换

[root@localhost sh]# sed '2c No such person ' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
No such person 
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# 
[root@localhost sh]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  7.8G  8.5G  48% /
tmpfs                 931M   76K  931M   1% /dev/shm
/dev/sda1             477M   41M  411M   9% /boot
/dev/sdb1             2.0G  3.1M  1.9G   1% /disk1
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
/dev/sr0              1.1G  1.1G     0 100% /media/Ubuntu 14.04.5 LTS amd64
[root@localhost sh]# 
[root@localhost sh]# df -h | sed -n '2p' 
/dev/mapper/VolGroup-lv_root

示例5、字符串替换

#sed 's/旧字串/新字串/g' 文件名

#sed '3s/74/99/g' student1.txt

#在第三行中,把74换成99

#sed -i '3s/74/99/g' student1.txt

#sed 操作的数据直接写入文件

#sed -e 's/Liming//g;s/Gao//g' student1.txt

#同时把“Liming” 和“Gao”替换为空

[root@localhost sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# sed '4s/99/55/g' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	55	83	93	81.66
[root@localhost sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[root@localhost sh]# sed -i '4s/99/55/g' student1.txt 
[root@localhost sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	55	83	93	81.66
[root@localhost sh]# 

注意对比上方的第四行第三列的数据变化,以及对比文件内容在修改前后是否变化。

建议需要修改文件时使用vim 命令,不需要修改文件时,使用sed命令

 

 

 

 

 

 

你可能感兴趣的:(Linux)