Shell脚本字符串处理(Linux篇)
1.字符串处理
1.1.cut
cut
命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。语法格式如下:
命令格式: cut [选项] 文件名
选项参数说明:
选项 | 说明 |
---|---|
-b | 选中第几个字符 |
-c | 选中多少个字符 |
-d | 按照指定分割符进行分割,默认的分割符是制表符,注意分割符不能使用空格。 |
-f | 提取第几列 |
示例一:初识cut命令
# 打印 b 字符:
root@zking:~# echo "acbdef" | cut -b 2
c
# 截取 abc 字符:
root@zking:~# echo "acbdef" | cut -c 1-3
acb
# 以冒号分隔,显示第二个字段:
root@zking:~# echo "a:b:c" | cut -d: -f 2
b
示例二:提取列
root@zking:~# vim person.txt
# 请使用tab键来完成制表符分隔处理
ID NAME SEX AGE
1 zs m 21
2 ls m 22
3 ww m 23
4 xq w 19
# 通过-f 2指明提取第2列
root@zking:~# cut -f 2 person.txt
NAME
zs
ls
ww
xq
# 通过-f 2-3或者-f 2,3指明提取的多列
# 其中-f 2-3代表提取第2列到第3列
# 其中-f 2,3代表提取第2列和第3列
# 有区别噢!!!
root@zking:~# cut -f 2-3 person.txt
NAME SEX
zs m
ls m
ww m
xq w
示例三:指定分隔符
# 通过-d选项指定分隔符
root@zking:~# cut -d : -f 1,3 /etc/group
root:0
daemon:1
bin:2
sys:3
...
# 通过管道符
root@zking:~# cat /etc/passwd | cut -d : -f 1,2,3
root:x:0
daemon:x:1
bin:x:2
sys:x:3
...
示例四:cut的局限性
# cut的局限性,提取第五列没有作用,因为分隔符是连续的空格,而不是制表符
root@zking:~# df -h | cut -f 5
Filesystem Size Used Avail Use% Mounted on
tmpfs 193M 1.3M 192M 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 9.8G 7.7G 1.6G 84% /
tmpfs 964M 0 964M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 1.8G 253M 1.4G 16% /boot
tmpfs 193M 4.0K 193M 1% /run/user/1000
# 指定分隔符为空格符也不行,因为不知道到底又几个空格
root@zking:~# df -h | cut -d " " -f 5
7.7G
root@zking:~#
1.2.awk
1.2.1.printf
printf
命令格式化输出,默认打印字符串不换行。格式化输出命令:
printf '输出类型输出格式' 输出内容
输出类型说明:
输出类型 | 说明 |
---|---|
%ns | 输出字符串,n表示输出几个字符 |
%ni | 输出整数,n表示输出几个数字 |
%m.nf | 输出浮点数,m表示输出的总位数,n表示小数点的位数 |
输出格式说明:
输出格式 | 说明 |
---|---|
\a | 输出警告音 |
\b | 输出退格键 |
\f | 清除屏幕 |
\n | 换行 |
\r | 回车 |
\t | 水平方向tab |
\v | 垂直方向tab |
示例一:
root@zking:~# printf %s 1 2 3 4 5
12345root@zking:~#
# 下面的写法不可以,需要用单引号将类型说明引起来,下面又正确的示例
root@zking:~# printf %s %s %s 1 2 3 4 5 6
%s%s123456root@zking:~#
# 1 2 3 最为一组字符的,4 5 6作为一组, 中间没有换行
# 输出一组后加一个换行
root@zking:~# printf '%s %s %s\n' 1 2 3 4 5 6
1 2 3
4 5 6
# 如果需要从文件中获取,则可以如下写法:
root@zking:~# printf '%s' $(cat person.txt)
IDNAMESEXAGE1zsm212lsm223wwm234xqw19root@zking:~#
# printf不能和管道符一起使用,
root@zking:~# printf '%s' | $(cat person.txt)
ID: command not found
# 获取文件内容通过\t制表符输出
root@zking:~# printf '%s\t %s\t %s\t %s\n' $(cat person.txt)
ID NAME SEX AGE
1 zs m 21
2 ls m 22
3 ww m 23
4 xq w 19
1.2.2.awk
awk
是一个处理文本的编程语言工具,能用简短的程序处理标准输入或文件、数据排序、计算以及生成报表等等。 基本的命令语法:awk option 'pattern {action}' file
其中
pattern
表示AWK
在数据中查找的内容,而action
是在找到匹配内容时所执行的一系列命令。 花括号用于根据特定的模式对一系列指令进行分组。
option
选项说明:
选项 | 说明 |
---|---|
-f program-file | 从文件中读取 awk 程序源文件 |
-F fs | 指定 fs 为输入字段分隔符 |
-v var=value | 变量赋值 |
--posix | 兼容 POSIX 正则表达式 |
--dump-variables=[file] | 把 awk 命令时的全局变量写入文件,默认文件是 awkvars.out |
--profile=[file] | 格式化 awk 语句到文件,默认是 awkprof.out |
示例一:
# 注意:\t制表符必须要使用双引号包裹,这里也不能使用单引号
root@zking:~# awk '{printf $2 \t $4 \t}' person.txt
awk: cmd. line:1: {printf $2 \t $4 \t}
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: {printf $2 \t $4 \t}
awk: cmd. line:1: ^ syntax error
# 没有指定条件,即输出所有行,动作是使用printf进行格式化输出
# {}部分表示动作
root@zking:~# awk '{print $2 "\t" $4}' person.txt
NAME AGE
zs 21
ls 22
ww 23
xq 19
# print会在行末自动加换行符
root@zking:~# df -h | awk '{print $1 "\t" $5 "\t" $6}'
Filesystem Use% Mounted
tmpfs 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 84% /
tmpfs 0% /dev/shm
tmpfs 0% /run/lock
/dev/sda2 16% /boot
tmpfs 1% /run/user/1000
# 使用管道符将多个命令组合使用
root@zking:~# df -h | grep 'sda2' | awk '{printf $5}' | cut -d "%" -f 1
16
# 通过FS指定分割符
root@zking:~# awk '{FS=":"} {print $1 "\t" $3}' /etc/passwd
# 第一行格式不符合要求
root:x:0:0:root:/root:/bin/bash
daemon 1
bin 2
sys 3
...
# 使用begin在读入第一行之前是设置分割符生效
root@zking:~# awk 'BEGIN{FS=":"} {printf $1 "\t" $3 "\n"}' /etc/passwd
root 0
daemon 1
bin 2
...
# 在输出之前先设置分割符,在输出完后提示一个end
root@zking:~# awk 'BEGIN{FS=":"} END{print "end...."} {printf $1 "\t" $3 "\n"}' /etc/passwd
root 0
daemon 1
bin 2
...
end....
# 首选读取person文件数据,并传给awk命令,awk命令选取第四列大于等于22的数据(年龄)
root@zking:~# cat person.txt | awk '$4 >=22 {print}'
ID NAME SEX AGE
2 ls m 22
3 ww m 23
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的默认行为
root@zking:~# sed '2p' person.txt
ID NAME SEX AGE
1 zs m 21
1 zs m 21
2 ls m 22
3 ww m 23
4 xq w 19
# 如果不想输出其他行,则需要使用n参数
root@zking:~# sed '2p' -n person.txt
1 zs m 21
# 使用cat查看原文件内容,发现内容没有被改变
root@zking:~# cat person.txt
ID NAME SEX AGE
1 zs m 21
2 ls m 22
3 ww m 23
4 xq w 19
# 和管道符结合的示例
root@zking:~# cat person.txt | sed '2p' -n
1 zs m 21
# 删除2,3行数据,注意只是在结果中删除,不会在文件中删除,可以使用cat命令进行验证
root@zking:~# sed '2,3d' person.txt
ID NAME SEX AGE
3 ww m 23
4 xq w 19
root@zking:~# cat person.txt
ID NAME SEX AGE
1 zs m 21
2 ls m 22
3 ww m 23
4 xq w 19
# 追加数据,同样不会影响源文件,因为没有使用-i参数
# 这里5a表示在第5行追加数据
root@zking:~# sed '5a 5\tzl\tw\t23' person.txt
ID NAME SEX AGE
1 zs m 21
2 ls m 22
3 ww m 23
4 xq w 19
5 zl w 23
# 替换第四行(行替换),不会影响原文件
root@zking:~# sed '3c tihuanhang' person.txt
ID NAME SEX AGE
1 zs m 21
tihuanhang
3 ww m 23
4 xq w 19
# 指定字符串替换,不会影响原文件
root@zking:~# sed '4s/23/52/g' person.txt
ID NAME SEX AGE
1 zs m 21
2 ls m 22
3 ww m 52
4 xq w 19
# 指定字符串替换,通过-i选项,直接更改了源文件内容
root@zking:~# sed -i '4s/23/52/g' person.txt
root@zking:~# cat person.txt
ID NAME SEX AGE
1 zs m 21
2 ls m 22
3 ww m 52
4 xq w 19
1.4.sort
sort
命令实现排序文本,默认对整列有效。命令格式:
sort [选项] 文件名
选项说明:
选项 | 说明 |
---|---|
-f | 忽略大小写 |
-n | 数值型排序 |
-r | 反向排序 |
-t | 指定分割符,默认为制表符 |
-k n,[m] | 用指定的字段范围排序, 如果不指定m,则表示从n到行尾 |
示例一:
# 默认整行升序
root@zking:~# sort /etc/passwd
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
....
# 通过-r设置降序
root@zking:~# sort -r /etc/passwd
zking:x:1000:1000:zking:/home/zking:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
virtual:x:1002:1002::/home/vftproot:/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
...
# 对passwd文件,使用”:”作为分割符,去第三个字段进行排序,
# 在排序时将第三字段作为数字(不指定-n则默认作为字符排序)
# 上述的作用即:使用uid数字对passwd文件进行排序
root@zking:~# sort -n -t":" -k 3,3 /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
...
1.5.wc
wc
命令用于统计文件行数、字节、字符数。命令格式:
wc [选项] 文件名
选项说明:
选项 | 说明 |
---|---|
-l | 只统计行数 |
-w | 只统计单词数 |
-m | 只统计字符数 |
示例一:
root@zking:~# wc person.txt
# 5行 20个单词 56个字符
5 20 56 person.txt
root@zking:~#
# 统计行数
root@zking:~# wc -l person.txt
5 person.txt
# 统计单词数
root@zking:~# wc -w person.txt
20 person.txt
# 统计字符数
root@zking:~# wc -m person.txt
56 person.txt