shell 字符串处理
shell文本处理三剑客之grep、awk、sed
1、cut 列提取命令
作用:按列提取文件
cut [选项] 文件名
选项:
-f 列号: 提取第几列 form a line
-d 分隔符: 按照指定分隔符分割列division
-c 字符范围: 不依赖分隔符来区分,而是通过字符范围(行首为0)来进行字段提取。“n-”
表示从第n个字符到行尾;“n-m" 从第n个i字符到第m个字符;”-m“ 表示从第一个字符到第m个字符。char
注意事项:cut是没有办法提取空格,cut的默认分隔符是制表符Tab。可以使用awk来进行处理
文件:
gjl@gjl-virtual-machine:~/shellTest$ cat test08.txt name sex phone jacj boy 113213 hhs girl 213423 sdf boy 23432 ashdfk:72ruqwi:uyfdsi:uyifds:jhdsfiaf
例如1:提取第二列 gjl@gjl-virtual-machine:~/shellTest$ cut -f 2 test08.txt sex boy girl boy
ashdfk:72ruqwi:uyfdsi:uyifds:jhdsfiaf
例如2:提取文件中以:分割的第三列 gjl@gjl-virtual-machine:~/shellTest$ cut -d ":" -f 3 test08.txt name sex phone jacj boy 113213 hhs girl 213423 sdf boy 23432 uyfdsi
例如三:提取文件中只有以:为分割线的第三列 gjl@gjl-virtual-machine:~/shellTest$ grep ":" test08.txt | cut -d ":" -f 3 uyfdsi
例如四:提取文件中以:为分割线,第三列中第二到第三个字符 gjl@gjl-virtual-machine:~/shellTest$ grep ":" test08.txt | cut -d ":" -f 3 | cut -c 2-3 yf gjl@gjl-virtual-machine:~/shellTest$
2、awk函数
作用:格式化文本,对文本进行较复杂格式处理
①printf 格式化输出
printf ‘输出类型输出格式‘ 输出内容
输出类型:%ns 输出字符串,n是代表输出几个字符string
%ni 输出整数,n是代表输出几个数字int
%m.nf输出浮点数,mn是数字,指代输出的整数和小数位数。如:%8.2f,代表共输出6位数,其中2为小数,6为整数fload
注意事项:如果不指定输出格式。默认输出字符串
使用单引号
先调用其他指令,最后调用格式处理
使用print,自动换行,printf 需要转义符\n
例如1:去除文件中非表格内容的项,然后将一二列输出字符串,第三列输出整型,第四列输出浮点型(6位,其中2位小数,4位整数)
gjl@gjl-virtual-machine:~/shellTest$ printf '%s\t %s\t %i\t %6.2f\t \n' $(cat test08.txt | grep -E -v '(name|ashd)')
②awk 基本使用
awk ’条件1{动作1} 条件2{动作2}....' 文件名
注意事项:如果使用awk,动作如果使用printf,需要使用双引号,区别单独使用printf
awk 需要使用单引号
执行顺序,先读取行,在读取列
awk 保留字 BEGIN 在程序一开始,尚未读取任何数据之前执行。BEGIN后的动作只在程序开始时执行
END 在程序处理完所有数据,即将结束时执行
关系运算符 < 、> 、 >= 、 <=、 == 、!=
A~B 判断字符串a是否包含匹配b表达式的字符串
A!~B 判断a字符串中是否不包含b表达式的子字符串
/正则/ //中可以写入字符或者正则表达式
例如1、输出第二列和第四列
gjl@gjl-virtual-machine:~/shellTest$ awk '{printf $2 "\t"$4 "\n"}' test08.txt sex score boy 12 girl 23.34 boy 123.4444
例如2、读取成绩大于23的学生
gjl@gjl-virtual-machine:~/shellTest$ cat test08.txt | grep -E -v '(name|ashd)' | awk ' $4 >= 23 {print $1 }' hhs sdf
例如3、查询出性别为男的学生
gjl@gjl-virtual-machine:~/shellTest$ awk '$2~/boy/ {print $1}' test08.txt jacj sdf
例如4、查询出文件中包含boy的项
gjl@gjl-virtual-machine:~/shellTest$ awk '/boy/ {print $1}' test08.txt jacj boy sdf
③awk 内置变量
$0 代表目前所读入的整行数据
$n 代表目前读入行的第几个字段
NF 当前行所拥有的字段列总数
NR 当前awk所处理的行是总数据的第几行
FS 用户定义分隔符。awk的默认分隔符是任何空格。如果想要使用分隔符,就需要FS变量定义
ARGC 命令行参数个数
ARGV 命令行参数数组
FNR 当前文件中的当前记录数(对输入文件起始为1)
OFMT 数值的输出格式(默认为%.6g))
OFS 输出字段的分隔符(默认为空格)
ORS 输出记录分隔符(默认为换行符)
RS 输入记录分隔符(默认为换行符)
例如1、输出以冒号为分隔符的第一列
gjl@gjl-virtual-machine:~/shellTest$ grep ":" test08.txt | awk 'BEGIN{FS=":"} {print $1}'
注意事项:需要加begin,因为awk读取顺序是先行,在列。如果不加,会导致先读取了第一行,再去判断列中“:”号。
例如2、读取指定行
gjl@gjl-virtual-machine:~/shellTest$ grep ":" test08.txt | awk 'BEGIN{FS=":"}$2=="72ruqwi" {print $1}'
例如2、读取行号和列号
gjl@gjl-virtual-machine:~/shellTest$ cat test08.txt | grep ":" | awk 'BEGIN{FS=":"}{print $1"\t""hanghao:"NR"\t""liehao:\t" NF "\n" }' ashdfk hanghao:1 liehao: 5 ashdfk hanghao:2 liehao: 5 ashdfk hanghao:3 liehao: 5
注意事项:变量不用双引号,字符串需要双引号
3、sed 命令
作用:用来将数据进行选取、替换、删除、新增的命令。即编辑文件
格式: sed [选项] ‘[动作]’ 文件名
选项:
-n 一般sed命令会把所有数据都输出到屏幕 ,如果加入次选择,则只会把经过sed命令处理的行输入到屏幕
-e 允许对输入数据应用多条sed命令编辑edit
-i 用sed的修改结果直接修改读取的数据的文件,而不是由屏幕输出动作 insert
-r 在sed中支持扩展正则表达式
动作:
d 删除指定行
p 打印,输出指定的行
a \ 追加,在当前行后添加一行或多行。除最后一行外,每行末尾都要加、代表数据未完成
c \ 行替换,在c后面的字符串替换原来的数据行。
i \ 插入,在当前行前插入一行或多行
s 字串替换,用一个字符串替换另外一个字符串,格式为“行范围s/旧字符串/新字符串/g”
例如1:输出指定的行。注意事项:需要加入-n,不然会重复打印指定的行,并且会把其他的行打印出来
gjl@gjl-virtual-machine:~/shellTest$ sed -n '2p' test08.txt jacj boy 113213 12 gjl@gjl-virtual-machine:~/shellTest$ sed '2p' test08.txt name sex phone score jacj boy 113213 12 jacj boy 113213 12 boy girl 213423 23.34 sdf boy 23432 123.4444 boyqw boy12 12 23 ashdfk:ruqwi:uyfdsi:uyifds:jhdsfiaf ashdfk:72ruqwi:uyfdsi:uyifds:jhdsfiaf ashdfk:72ruqwi:uyfdsi:uyifds:jhdsfiaf gjl@gjl-virtual-machine:~/shellTest$
例如2.删除指定的行.注意事项:如果前面加入-i,则会将文件中的内容直接删除,不加,源文件中内容没有被删除
gjl@gjl-virtual-machine:~/shellTest$ sed '2,4d' test08.txt name sex phone score boyqw boy12 12 23
例如3.在列表中追加和替换、插入第二行
追加: gjl@gjl-virtual-machine:~/shellTest$ sed -i '2a 1232hdasjkd ' test08.txt gjl@gjl-virtual-machine:~/shellTest$ cat test08.txt name sex phone score jacj boy 113213 12 1232hdasjkd boy girl 213423 23.34 sdf boy 23432 123.4444 boyqw boy12 12 23 插入: gjl@gjl-virtual-machine:~/shellTest$ sed -i '2i caozuo ' test08.txt gjl@gjl-virtual-machine:~/shellTest$ cat test08.txt name sex phone score caozuo jacj boy 113213 12 1232hdasjkd boy girl 213423 23.34 sdf boy 23432 123.4444 boyqw boy12 12 23 替换: gjl@gjl-virtual-machine:~/shellTest$ sed -i '2c ok' test08.txt gjl@gjl-virtual-machine:~/shellTest$ cat test08.txt name sex phone score ok jacj boy 113213 12 1232hdasjkd boy girl 213423 23.34 sdf boy 23432 123.4444 boyqw boy12 12 23
例如4.用55.6替换55.6;
gjl@gjl-virtual-machine:~/shellTest$ sed -i -e 's/55.6;/55.6/' test08.txt gjl@gjl-virtual-machine:~/shellTest$ cat test08.txt name sex phone score meim girl 12565665896 55.6 dk girl 12565665896 96 jack boy 12565665896 99.6 maoo boy 12565235896 44.6 maoo boy 1256536 55.6 gjl@gjl-virtual-machine:~/shellTest$
4、字符处理命令
①排序命令 sort
格式: sort [选项] 文件名
选项:
-f 忽略大小写
-b 忽略每行前面的空白部分
-n 以数值型进行排序,默认使用字符串型排序
-r 反向排序
-u 删除重复行
-t 指定分隔符,默认分隔符是制表符
②uniq
作用:取消重复行的命令,和sort -u 选项一样
格式:uniq [选项] 文件名
选项:
-i 忽略大小写
③统计命令 wc
格式: wc [选项] 文件名
选项:
-l 只统计行数
-w 只统计单词数
-m 只统计字符数
例如1: 统计test08.txt 文件的行数,单词数,字符数
gjl@gjl-virtual-machine:~/shellTest$ sort test08.txt dk girl 12565665896 96 jack boy 12565665896 99.6 maoo boy 12565235896 44.6 maoo boy 1256536 55.6 meim girl 12565665896 55.6 name sex phone score gjl@gjl-virtual-machine:~/shellTest$ wc test08.txt 6 24 164 test08.txt