shell字符截取与字符处理命令
2017-04-19 00:00
357 查看
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
相关文章推荐
- 批处理命令set截取字符详解
- Shell-字符截取命令-sed命令
- 【shell】expr命令---数值计算+字符处理
- Shell 常用字符处理命令cut/sort/wc/uniq/tee/tr/split
- shell-字符处理命令/条件判断
- shell字符截取命令之awk命令
- Linux系统命令及Shell脚本学习笔记五:字符处理
- [Shell]字符截取命令:cut, printf, awk, sed
- shell 字符(串)处理命令
- shell-字符截取命令sed
- shell字符截取命令之cut命令的实例详解
- Linux Shell编程-字符截取和处理命令
- shell笔记(5):字符截取命令
- Shell-字符处理命令
- shell字符处理命令,通配符,正则表达式
- shell字符截取命令之cut命令
- [Shell]字符截取命令:cut, printf, awk, sed
- Shell 字符截取命令:cut, printf, awk, sed
- shell中字符提取命令awk和cut的不同
- 关于截取带html标签的文字的前n个字符的处理(需求一)