文档章节

shell字符截取与字符处理命令

海军战士
 海军战士
发布于 2017/04/19 23:29
字数 3149
阅读 34
收藏 1

1.使用cut命令截取列

grep适用于截取行的,cut是用于截取列的

1.1 用-f选项指定提取的列

###创建score.txt文件用于测试(注意列之间并不是空格,而是制表符,及Tab键)
[root@wenhaijin ~]# vim score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
2       LISI    M       85
3       WANGWU  M       75


###截取第二列和第四列
[root@wenhaijin ~]# cut -f 2,4 score.txt
NAME    SCORE
ZHANGSAN        90
LISI    85
WANGWU  75

1.2 cut使用-d指定列的分隔符(默认的分隔符就是制表符)

有些文件并不是以制表符进行分割的,比如/etc/passwd文件使用":"来 分割列的,

这样我们就可以用cut -d ":"来进行提取

###截取用户列表(第一列)和用户id(第三列)
[root@wenhaijin ~]# 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
user1:503
user2:504
user3:505

1.3 在实际应用中,cut经常是配合grep进行使用

###找出普通用户(命令保存在/bin/bash下)
[root@wenhaijin ~]# cat /etc/passwd | grep /bin/bash
root:x:0:0:root:/root:/bin/bash
mysql:x:498:500::/home/mysql:/bin/bash
wenhaijin:x:500:501::/home/wenhaijin:/bin/bash
whj:x:501:502::/home/whj:/bin/bash
fuzhoudaxue:x:502:503::/home/fuzhoudaxue:/bin/bash
user1:x:503:506::/home/user1:/bin/bash
user2:x:504:507::/home/user2:/bin/bash
user3:x:505:509::/home/user3:/bin/bash
[root@wenhaijin ~]# 

###过滤掉超级用户(使用grep -v取反)
[root@wenhaijin ~]# cat /etc/passwd | grep /bin/bash | grep -v root
mysql:x:498:500::/home/mysql:/bin/bash
wenhaijin:x:500:501::/home/wenhaijin:/bin/bash
whj:x:501:502::/home/whj:/bin/bash
fuzhoudaxue:x:502:503::/home/fuzhoudaxue:/bin/bash
user1:x:503:506::/home/user1:/bin/bash
user2:x:504:507::/home/user2:/bin/bash
user3:x:505:509::/home/user3:/bin/bash
[root@wenhaijin ~]# 

###只显示用户名
[root@wenhaijin ~]# cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ":" -f 1
mysql
wenhaijin
whj
fuzhoudaxue
user1
user2
user3
[root@wenhaijin ~]# 

###后续如果需要对除root用户外的所有普通用户进行相关处理(比如删除),就可以使用该命令,
将该命令的执行结果当做参数传递给shell脚本就行相关逻辑操作

cut命令比较简单,它的缺点是不能很好地使用cut -d " "来进行截取,因为有些列之间可能不止一个空格,cut会将第一个空格当做分隔符,第二个空格当做列,第三个空格又当做分隔符……

###以下是想得到根分区所在磁盘的使用百分比
###先查看系统所有分区
[root@wenhaijin ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  7.3G   30G  20% /
tmpfs           939M  4.0K  939M   1% /dev/shm

###使用根分区的特性进行过滤
[root@wenhaijin ~]# df -h | grep "vda1"
/dev/vda1        40G  7.3G   30G  20% /

###使用cut -f 提取第五列(提取失败,说明并不是以制表符进行分割的)
[root@wenhaijin ~]# df -h | grep "vda1" | cut -f 5
/dev/vda1        40G  7.3G   30G  20% /

###使用空格来分割列,(答应出的是空格,因为第一列和第二列中有多个空格)
[root@wenhaijin ~]# df -h | grep "vda1" | cut -d " " -f 5

[root@wenhaijin ~]# 

2.格式化输出命令printf

严格意义上说,printf并不是文件提取命令,也没有cat和echo使用起来方便。但是在awk中,不能直接调用cat和echo,而是需要通过调用printf来打印一些信息

2.1 printf

 

 

###使用printf打印上面的分数表内容score.txt
[root@wenhaijin ~]# printf '%s\t %s\t %s\t %s\n' $(cat score.txt)
ID       NAME    SEX     SCORE
1        ZHANGSAN        F       90
2        LISI    M       85
3        WANGWU  M       75
[root@wenhaijin ~]# 

2.2 awk中print与printf的区别

print会在输出后自动加入换行符,但print并不是linx系统命令,所以不能在系统中直接调用

 

3 awk命令

3.1 awk命令的用法

 

###使用awk命令输出score.txt的姓名(第二列)和成绩(第四列)
[root@wenhaijin ~]# awk '{printf $2 $4}' score.txt 
NAMESCOREZHANGSAN90LISI85WANGWU75[root@wenhaijin ~]# 

###配合制表符和换行符进行格式化
[root@wenhaijin ~]# awk '{printf $2 "\t" $4"\n"}' score.txt 
NAME    SCORE
ZHANGSAN        90
LISI    85
WANGWU  75
[root@wenhaijin ~]# 

###查看磁盘使用情况
[root@wenhaijin ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  7.3G   30G  20% /
tmpfs           939M  4.0K  939M   1% /dev/shm

###查看第一列,第五列,第六列(未进行格式化)
[root@wenhaijin ~]# df -h | awk '{printf $1 "\t" $5 "\t" $6}'
Filesystem      Use%    Mounted/dev/vda1        20%     /tmpfs  1%      /dev/shm

###print自带换行功能
[root@wenhaijin ~]# df -h | awk '{print $1 "\t" $5 "\t" $6}'
Filesystem      Use%    Mounted
/dev/vda1       20%     /
tmpfs   1%      /dev/shm
[root@wenhaijin ~]# 

###查看根分区使用情况(第五列)
[root@wenhaijin ~]# df -h | grep vda1 | awk '{print $5}'
20%

###只提取根分区数字,不显示百分比
[root@wenhaijin ~]# df -h | grep vda1 | awk '{print $5}' | cut -d "%" -f 1
20


3.2 BEGIN用法

BEGIN在所有的awk条件执行之前执行,且只执行一次

 

###在打印学生成绩之前打印一句话
[root@wenhaijin ~]# awk 'BEGIN{print "The of all students is bellow:"} {printf $2 "\t" $4"\n"}' score.txt 
The of all students is bellow:
NAME    SCORE
ZHANGSAN        90
LISI    85
WANGWU  75
[root@wenhaijin ~]# 

3.3 用FS内置变量用来指定分隔符

/etc/passwd是用":"分割的,用FS指定分隔符

###打印出密码文件中的用户名和用户ID
[root@wenhaijin ~]# 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
vcsa    69
abrt    173
haldaemon       68
ntp     38
saslauth        499
postfix 89
sshd    74
tcpdump 72
nscd    28
mysql   498
wenhaijin       500
whj     501
fuzhoudaxue     502
user1   503
user2   504
user3   505
[root@wenhaijin ~]# 

从上面的输出结果可以看出,awk命令并没有对第一行进行处理,原因是awk在处理的时候是先读取第一行数据,然后再执行后面的操作,也就是说在上面的awk命令中,通过FS指定分隔符之前,第一行数据已经被读入,后面的按列输出处理就来不及了。对于第一行,awk其实是采用默认的空格来进行分割

解决方法就是通过3.2中的BEGIN命令来处理

###使用BEGIN命令,表示在读取第一行数据前就先指定分隔符
[root@wenhaijin ~]# 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
vcsa    69
abrt    173
haldaemon       68
ntp     38
saslauth        499
postfix 89
sshd    74
tcpdump 72
nscd    28
mysql   498
wenhaijin       500
whj     501
fuzhoudaxue     502
user1   503
user2   504
user3   505
[root@wenhaijin ~]# 

3.4 END的用法

在awk命令中,END所指定的操作会在所有操作执行完成之后再执行,END条件操作不一定要写在最后,跟书写顺序无关

[root@wenhaijin ~]# awk 'BEGIN{print "The of all students is bellow:"} END{print "This is the endding!"} {printf $2 "\t" $4"\n"}' score.txt 
The of all students is bellow:
NAME    SCORE
ZHANGSAN        90
LISI    85
WANGWU  75
This is the endding!
[root@wenhaijin ~]# 

3.5 awk条件运算符的使用

[root@wenhaijin ~]# cat score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 

###打印出成绩大于或等于80分的学生姓名
[root@wenhaijin ~]# cat score.txt | grep -v name | awk '$4 >= 80 {print $2}'
NAME
ZHANGSAN
LISI
[root@wenhaijin ~]# 

4 sed命令

 

sed的选项一定要用单引号括起来,sed对应的当做有下面几种:

 

4.1 sed命令可以处理文件

###输出score.txt的第二行信息,结果是所有信息都输出,第二行输出了两遍
[root@wenhaijin ~]# sed "2p" score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
1       ZHANGSAN        F       90
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 

###采用-n选项只输出sed过滤的行
[root@wenhaijin ~]# sed -n "2p" score.txt 
1       ZHANGSAN        F       90
[root@wenhaijin ~]# 

4.2 sed命令是流编辑器,他也能放在管道符之后处理前面输出的内容

###打印df -h 中的第二行数据
[root@wenhaijin ~]# df -h | sed -n "2p"
/dev/vda1        40G  5.9G   32G  16% /
[root@wenhaijin ~]# 

4.3 sed删除行

###sed删除文件的第二行到第四行
[root@wenhaijin ~]# sed "2,4d" score.txt 
ID      NAME    SEX     SCORE

###sed删除文件的第三行
[root@wenhaijin ~]# sed "3d" score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
3       WANGWU  M       75

###查看文件发现 文件真正的内容并没有被删除
[root@wenhaijin ~]# cat score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 

4.4 追加与插入

###在第二行后追加一行:hello-world
[root@wenhaijin ~]# sed '2a hello-world' score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
hello-world
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]#

###在第二行前插入:hello-kitty
[root@wenhaijin ~]# sed '2i hello-kitty' score.txt 
ID      NAME    SEX     SCORE
hello-kitty
1       ZHANGSAN        F       90
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 

###在第二行前面同时插入两行
[root@wenhaijin ~]# sed '2i hello-kitty1 \
> hello-kitty2' score.txt
ID      NAME    SEX     SCORE
hello-kitty1 
hello-kitty2
1       ZHANGSAN        F       90
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 

4.5 sed字符替换

行替换

[root@wenhaijin ~]# cat score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
2       LISI    M       85
3       WANGWU  M       75

###将第四行替换成Only two person
[root@wenhaijin ~]# sed '4c Only two person' score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
2       LISI    M       85
Only two person
[root@wenhaijin ~]# 

 

###替换张三的成绩为60分
[root@wenhaijin ~]# sed '2s/90/60/g' score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       60
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 

###以上操作的只是输出内容,并没有真正改变文件
[root@wenhaijin ~]# cat score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       90
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 

###将张三的成绩改成80分并写入文件
[root@wenhaijin ~]# sed -i '2s/90/80/g' score.txt 
[root@wenhaijin ~]# cat score.txt 
ID      NAME    SEX     SCORE
1       ZHANGSAN        F       80
2       LISI    M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 

###多行替换,未指定行及替换整个文档,将张三改为赵六,李四改为空
[root@wenhaijin ~]# sed -e 's/ZHANGSAN/ZHAOLIU/g ; s/LISI//g' score.txt 
ID      NAME    SEX     SCORE
1       ZHAOLIU F       80
2               M       85
3       WANGWU  M       75
[root@wenhaijin ~]# 



5 字符处理命令

5.1 字符排序

 

###按字符顺序对/etc/passwd进行排序
[root@wenhaijin ~]# sort /etc/passwd
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
tcpdump:x:72:72::/:/sbin/nologin
user1:x:503:506::/home/user1:/bin/bash
user2:x:504:507::/home/user2:/bin/bash
user3:x:505:509::/home/user3:/bin/bash
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
wenhaijin:x:500:501::/home/wenhaijin:/bin/bash
whj:x:501:502::/home/whj:/bin/bash

###按字母顺序反向排序
[root@wenhaijin ~]# sort -r /etc/passwd
whj:x:501:502::/home/whj:/bin/bash
wenhaijin:x:500:501::/home/wenhaijin:/bin/bash
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
user3:x:505:509::/home/user3:/bin/bash
user2:x:504:507::/home/user2:/bin/bash
user1:x:503:506::/home/user1:/bin/bash
tcpdump:x:72:72::/:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
[root@wenhaijin ~]# 

###按照第三列(用户ID)进行排序,用户ID虽然是数字类型,sort默认依然按字母来排
###指定分隔符是":",用第三个字段开头,第三个字段结尾(即只用第三个字段)排序
[root@wenhaijin ~]# sort -t ":" -k 3,3 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
wenhaijin:x:500:501::/home/wenhaijin:/bin/bash
whj:x:501:502::/home/whj:/bin/bash
user1:x:503:506::/home/user1:/bin/bash
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
[root@wenhaijin ~]# 

###通过-n选项指定以数字顺序排
[root@wenhaijin ~]# sort -n -t ":" -k 3,3 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
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
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
mysql:x:498:500::/home/mysql:/bin/bash
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
wenhaijin:x:500:501::/home/wenhaijin:/bin/bash
whj:x:501:502::/home/whj:/bin/bash
fuzhoudaxue:x:502:503::/home/fuzhoudaxue:/bin/bash
user1:x:503:506::/home/user1:/bin/bash
user3:x:505:509::/home/user3:/bin/bash
[root@wenhaijin ~]# 

5.2 统计命令wc

 

统计/etc/passwd文件

###这个文件有32行,42个单词,1388个字符
[root@wenhaijin ~]# wc /etc/passwd
  32   42 1388 /etc/passwd
[root@wenhaijin ~]# 

###只统计行数
[root@wenhaijin ~]# wc -l /etc/passwd
32 /etc/passwd

###只统计单词
[root@wenhaijin ~]# df -h | wc -w
19

###只统计字符数
[root@wenhaijin ~]# df -h | wc -m
136

 

© 著作权归作者所有

共有 人打赏支持
海军战士
粉丝 21
博文 138
码字总数 132831
作品 0
深圳
私信 提问
SHELL字符串处理技巧(${}、##、%%)

在SHELL编程中,经常要处理一些字符串变量。比如,计算长度啊、截取子串啊、字符替换啊等等,常常要用到awk、expr、sed、tr等命令。下面给大家介绍个简单的字符串处理方法,用不着嵌套复杂的...

Kerry_Han
2014/04/14
0
0
Linux-shell脚本字符串截取方法

  前言   在Linux shell编程中,我们经常需要截取某个字符串来,继续操作,比如:截取日期来创建整分钟的目录之类的。      字符截取   测试字符串   var=1234567890abcedef1203...

linux运维菜
2018/07/19
0
0
shell的特殊符号以及其他命令

shell特殊符号cut命令: cut -d (截取指定的符号分段) -f (截取的段落如果直接一个那么直接输入数字 1或者n 如果有多个那么在中间加上 , 或者 1-n ) cut -c 可以直接指定第几个字符,如...

叶瑾
2018/03/10
0
0
shell特殊符号、cut命令、sort_wc_uniq命令、tee_tr_split命令、shell特殊符号下

shell特殊符号 cut命令(截取列) -d 指定分隔符 -f 指定截取列 -c 指定第几个字符 sortwcuniq命令 sort 排序(不加选项按数字,字母顺序排序) -n 按数字顺序排序,字母比数字小 -r反向排序...

linux运维影魔
2018/03/07
0
0
linux命令经典用法与配置收录

1 管道或字符处理 1.1 grep的经典用法 1.1.1 扩展查找参数 grep -E 'vmx|svm' /proc/cpuinfo 1.1.2. 过滤注解和空行 grep -E -v "(^#|^$)" /etc/yum.conf 1.1.3 搜索文本的内容 grep –r "st......

tanzhenchao
2016/03/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

双亲委派模型

双亲委派模型的工作流程是: 如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到...

无精疯
5分钟前
0
0
原 分布式项目(三)CoAp

上回说到Web manage的构建,完成的对产品,物模型中的数据,设备数据,并把对应的数据缓存到redis中,接下来就开始coap客户端和服务器的构建。 coap 现阶段PC网络交互中较多的是使用tcp和htt...

lelinked
5分钟前
0
0
next.js 提示 chunk styles [mini-css-extract-plugin]

会出现css 导入警告 导入两个插件 并在next.config.js 配置 yarn add webpack-filter-warnings-pluginyarn add mini-css-extract-plugin const FilterWarningsPlugin = require('webpack-......

一箭落旄头
44分钟前
2
0
AWS的自动部署codeploy 应用程序规范文件

codedeploy应用程序的规范文件 ECS平台上的应用规范文件: AppSpec file也可以是 YAML 或 JSON 格式的,可以直接写入控制台内的编辑器内。 AppSpec file用于指定: 用于将流量定向到新任务集...

守护-创造
52分钟前
1
0
Confluence 6 超过当前许可证期限进行升级

这个页面将会对你在进行 Confluence 升级的时候超过了当前许可证的期限进行升级的情况。 许可证警告 在升级的过程中,你将会在 Confluence 的应用程序日志(log file)中看到类似下面的错误提...

honeymoose
58分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部