Shell之字符处理

一、字符处理

1.1 cut命令

命令格式: cut [选项] 文件名

选项:

  • -f 列号: 提取第几列
  • -d 分隔符: 按照指定分割符进行分割,默认的分割符是制表符,注意分割符不能使用空格。
  • 示例:
# 每个字段已制表符分割,不能是空格。
[root@localhost ~]# vi person.txt
ID Name sex age
1 ls m 18
2 zs m 25
3 ww w 22
[root@localhost ~]# cut -f 2 person.txt
Name
ls
zs
ww
[root@localhost ~]# cut -f 2,3 person.txt
Name sex
ls m
zs m
ww w
# 指定分割符的示例
[root@localhost ~]# cut -d ":" -f 1,3 /etc/passwd
root:0
bin:1
daemon:2
adm:3
lp:4
...
# 在管道符中使用的例子
[root@localhost ~]# cat /etc/passwd | cut -d ":" -f 1,3
root:0
bin:1
daemon:2
...
# cut的局限性,提取第五列没有作用,因为分隔符是连续的空格,而不是制表符
[root@localhost ~]# df -h | cut -f 5
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 475M 0 475M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 7.7M 479M 2% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 1.7G 16G 10% /
/dev/sda1 1014M 167M 848M 17% /boot
tmpfs 98M 0 98M 0% /run/user/0
[root@localhost ~]#

# 指定分隔符为空格符也不行,因为不知道到底又几个空格
[root@localhost ~]# df -h | cut -d " " -f 5

[root@localhost ~]#

1.2 awk命令

格式化输出命令:

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

输出类型:

  • %ns 输出字符串,n表示输出几个字符

  • %ni 输出整数,n表示输出几个数字

  • %m.nf 输出浮点数,m表示输出的总位数,n表示小数点的位数

输出格式:  

  • \a 输出警告音

  • \b 输出退格键

  • \f 清除屏幕

  • \n 换行

  • \r 回车
  • \t 水平方向tab
  • \v 垂直方向tab
[root@localhost ~]# printf %s 1 2 3 4 5
12345[root@localhost ~]#
# 下面的写法不可以,需要用单引号将类型说明引起来,下面又正确的示例
[root@localhost ~]# printf %s %s %s 1 2 3 4 5 6
%s%s123456[root@localhost ~]#
# 1 2 3 最为一组字符的,4 5 6作为一组, 中间没有换行
[root@localhost ~]# printf '%s %s %s' 1 2 3 4 5 6
1 2 34 5 6[root@localhost ~]#
# 输出一组后加一个换行
[root@localhost ~]# printf '%s %s %s\n' 1 2 3 4 5 6
1 2 3
4 5 6
# printf不能和管道符一起使用,如果需要从文件中获取,则可以如下写法:
[root@localhost ~]# printf '%s' $(cat person.txt)
IDNamesexage1lsm182zsm253www22[root@localhost ~]#
# 这样就可以了
[root@localhost ~]# printf '%s\t %s\t %s\t %s\n' $(cat person.txt)
ID Name sex age
1 ls m 18
2 zs m 25
3 ww w 22
# printf经常与awk一起使用

awk命令格式:

awk '条件1 {动作1} 条件2{动作2} ...' 文件名

条件:

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

x > 0

x >= 0

x <= 0

动作:

格式化输出,如printf

流程控制语句

示例:

# 没有指定条件,即输出所有行,动作是使用printf进行格式化输出
[root@localhost ~]# awk '{printf $2 "\t" $4 "\n"}' person.txt
Name age
ls 18
zs 25
ww 22
# print会在行末自动加换行符
[root@localhost ~]# df -h | awk '{print $1 "\t" $5 "\t" $6}'
文件系统 已用% 挂载点
devtmpfs 0% /dev
tmpfs 0% /dev/shm
tmpfs 2% /run
tmpfs 0% /sys/fs/cgroup
/dev/mapper/centos-root 10% /
/dev/sda1 17% /boot
tmpfs 0% /run/user/0
# 使用管道符将多个命令组合使用
[root@localhost ~]# df -h | grep sda1 | awk '{print $5}' | cut -d "%" -f 1
17
# 指定分割符
[root@localhost ~]# awk '{FS=":"} {print $1 "\t" $3}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
#第一行格式不符合要求,
bin 1
daemon 2
adm 3
# 使用begin在读入第一行之前是设置分割符生效
[root@localhost ~]# awk 'BEGIN{FS=":"} {print $1 "\t" $3}' /etc/passwd
root 0
bin 1
daemon 2
# 在输出之前先设置分割符,在输出完后提示一个end
[root@localhost ~]# awk 'BEGIN{FS=":"} END{print "end"} {print $1 "\t" $4}'
/etc/passwd
root 0
bin 1
daemon 2
adm 4
...
end
# 首选读取person文件数据,并传给awk命令,awk命令选取第四列大于等于20的数据(年龄),
# 并格式化输出第二列(名字)
[root@localhost ~]# cat person.txt | awk '$4 >= 20 {print $2 }'
Name
zs
ww

1.3 sed命令

适合所有的Unix及linux平台的轻量级的流编辑器,可以对数据进行选取,替换,删除,新增等操作。

注意:vim也可以编辑文件,但是不能用来修改命令结果中的内容,如使用管道符将前一个命令的结果

传给vim进行处理,这一点vim做不到。

命令格式:

sed [选项] '[动作]' 文件名

选项:

  • -n: sed命令会把所用的数据输出到屏幕,使用该选项则只会将sed命令处理的行输出到屏幕
  • -e: 允许对输入数据应用多条sed命令编辑
  • -i: 把sed的修改结果同步到数据文件中去,而不是屏幕。

动作:

  • a: 追加,在当前行后面追加一行或多行
  • c: 行替换,用c之后的字符串替换原来的数据,替换多行时,除最后一行外,每行需要用""表示数据未完
  • i: 插入,在当前行之前插入一行或多行,插入多行时,除最后一行外,每行需要用""表示数据未完结
  • d: 删除指定的行
  • p: 打印,输出指定的行
  • s: 字符串替换,格式为: “ 行范围s/需要替换的字符/替换的新字符/g”
# 2p 代表输出第二行,输出后又会将其他行输出,这是sed的默认行为,如果不想输出其他行
# 则需要使用n参数
[root@localhost ~]# sed '2p' person.txt
ID Name sex age
1 ls m 18
1 ls m 18
2 zs m 25
3 ww w 22
[root@localhost ~]# sed '2p' -n person.txt
1 ls m 18

# 和管道符结合的示例
[root@localhost ~]# cat person.txt | sed '2p' -n
1 ls m 18

# 删除2,3行数据,注意只是在结果中删除,不会在文件中删除,可以使用cat命令进行验证
[root@localhost ~]# sed '2,3d' person.txt
ID Name sex age
3 ww w 22
[root@localhost ~]# cat person.txt
ID Name sex age
1 ls m 18
2 zs m 25
3 ww w 22

# 追加数据,同样不会影响源文件,因为没有使用-i参数
[root@localhost ~]# sed '4a 4\ttq \tn\t23' person.txt
ID Name sex age
1 ls m 18
2 zs m 25
3 ww w 22
4 tq n 23

# 替换第四行(行替换),不会影响原文件
[root@localhost ~]# sed '4c tihuan' person.txt
ID Name sex age
1 ls m 18
2 zs m 25
tihuan

# 指定字符串替换,不会影响原文件
[root@localhost ~]# sed "3s/25/52/g" person.txt
ID Name sex age
1 ls m 18
2 zs m 52
3 ww w 22
、
# 这下把文件也替换了
[root@localhost ~]# sed -i "3s/25/52/g" person.txt
[root@localhost ~]# cat person.txt
ID Name sex age
1 ls m 18
2 zs m 52
3 ww w 22

1.4 字符串排序

命令格式:

sort [选项] 文件名

选项:

  • -f 忽略大小写
  • -n 数值型排序
  • -r 反向排序
  • -t 指定分割符,默认为制表符
  • -k n[,m] 用指定的字段范围排序, 如果不指定m,则表示从n到行尾。
[root@localhost ~]# sort /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
[root@localhost ~]# sort -r /etc/passwd
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
...
# 对passwd文件,使用”:”作为分割符,去第三个字段进行排序,
# 在排序时将第三字段作为数字(不指定-n则默认作为字符排序)
# 上述的作用即:使用uid数字对passwd文件进行排序
[root@localhost ~]# 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

统计命令wc

命令格式:wc [选项] 文件名

选项:

  • -l 只统计行数
  • -w 只统计单词数
  • -m 只统计单词数
[root@localhost ~]# wc person.txt
4 16 46 person.txt
# 文件有4行,16单词,46个字符
[root@localhost ~]# wc -l person.txt
4 person.txt
# 文件有4行

你可能感兴趣的:(linux,运维,服务器)