shell编程-字符截取命令

时间:2021-02-21 08:55:52

1. grep 命令

命令格式:grep [选项] 查找的字符串 文件名

作用:在文件中搜索查找字符串,显示匹配字符串所在的行。

选项:

-i:查找时忽略大小写。
-n:显示行号。
-v:反向查找(把不含有要搜索字符串的所有行显示出来)。
--color=auto:将匹配的关键字用颜色显示。

说明:[选项] 和 查找的字符串 之间的顺序可以互换。

查找的字符串可用引号(单引号或双引号)括起来,也可省略引号。

2. cut 命令

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

作用:提取(显示或查看)文件中的哪几列。

局限性:它不能提取多个空格分割的列,它可以识别的分隔符默认是制表符。

选项:

-f 列号:提取第几列。这个选项是必须选项。
-d 分隔符:按照手工指定的分隔符分割列。分隔符可以用双引号括起来。

示例:

cut -f 1  /etc/passwd
提取该文件中的第1列。(采用默认的制表符分割列)

cut -d ":" -f 1 /etc/passwd
提取该文件中的第1列。手工指定将":"作为列的分割符。

cut -d : -f 1,3 /etc/passwd
提取该文件中的第1列和第3列。(提取多列之后,会自动在列之间加上分隔符,然后再显示)

cut -d : -f 1,2,3 /etc/passwd
提取该文件中的第1列到第3列。

cut命令是提取文件中的列,而grep命令是提取文件中的行,因此,这两个命令经常需要配合使用。

示例:

cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ":" -f 1   
提取/etc/passwd文件中所有普通用户的用户名。

grep /bin/bash /etc/passwd | grep -v root | cut -d : -f 1
作用同上。

对于多个空格分割的列,无法用cut命令得到我们预期的结果。比如下面这条命令的显示结果就很尴尬。

df -h | cut -d " " -f 2

后面,我们会讲解awk命令,这个命令很复杂,但它可以解决这个问题。

3. printf 命令

严格来说,printf命令并不是字符提取命令。

命令格式:printf ‘输出格式’ 要输出的内容

作用:把要输出的内容,按照指定的格式匹配输出。

注意:printf不能直接输出文件中的内容,也不支持管道符。

输出格式(格式里可以加空格、字符或转义字符):

  • %ns:匹配字符串。n是数字,格式化为指定的长度时,如果长度不足,用填充符前置填充到指定的长度。默认的填充符是空格。
  • %ni:匹配整数。n是数字,作用同上。
  • %m.nf:匹配浮点数。m和n是数字,m代表浮点数的总位数,n代表小数位数(超出的话就四舍五入;不足的话,就用0在后面填充)。

注意:输出格式必须用引号括起来(单引号或双引号都行)。

示例:

[root@localhost profile.d]# printf '%s%s%s\n' 1 2 3 4 5 6
123
456

[root@localhost profile.d]# printf '%s%s%s\n' 1 2 3 4 5
123
45

[root@localhost profile.d]# printf '%sa%s%s\n' 1 2 3 4 5 6
1a23
4a56

[root@localhost profile.d]# printf '%s%s%s\n' "1 2 3 4 5 6"
1 2 3 4 5 6

[root@localhost profile.d]# printf '%5s\n' 1 2 3
1
2
3

[root@localhost profile.d]# printf '%5s\n' "123456"
123456

[root@localhost profile.d]# printf '%5s\n' "123"
123

[root@localhost profile.d]# printf '%8i\n' 3
3

[root@localhost profile.d]# printf '%5.2f\n' 3
3.00

printf 输出文件内容的方法:

[root@localhost ~]# printf '%s\t%s\t%s\t%s\n' $(cat /etc/issue)
CentOS release 6.6 (Final)
Kernel \r on an
\m

说明:

在awk命令的输出中支持printprintf

print会在每个输出之后,自动加上一个换行符。(Linux默认没有print命令)。
printf是以指定的标准格式输出,并不会自动加入换行符,一般都是手工加\n。

awk中使用的printprintf并不是Linux的命令,它们是awk中自带的。

4. awk 命令

awk不仅可以截取文件中的哪些列,而且它还是一门编程语言。功能很强大,操作起来比cut复杂得多。

截取列时,优先选择cut命令。如果cut命令不足以完成,就考虑awk命令。

awk可以识别的分隔符默认是制表符或空格(就算是多个没有规律的空格也可以识别)。

命令格式:awk ‘[条件1] {动作1} [条件2] {动作2} …’ 文件名

  • 条件:可省略,可用表达式作为条件。如果用BEGIN作为条件,则它后面的动作会优先执行;如果用END作为条件,则它后面的动作会最后执行。
  • 动作:格式化输出、流程控制语句等。

使用awk查看/etc/issue文件的第1列和第3列:

[root@localhost ~]# awk '{printf $1"\t"$3"\n"}' /etc/issue
CentOS 6.6
Kernel on

说明: nn n左右两侧可添加空格。

awk命令也可支持管道符。

示例:

df -h | awk '{printf $1 "\t" $5 "\n"}' 
将df -h的输出内容中的第1列和第5列,按照指定格式输出。

awk命令也会经常配合grep命令一起使用。

示例:

df -h | grep /dev/sda3 | awk '{printf $5 "\n"}' | cut -d % -f 1
通过该命令可以输出根分区的磁盘占用情况(除去了%),以便监测根分区。
这里,我事先知道/dev/sda3代表根分区。

在awk命令中,可用FS内置变量手工指定分割符。

示例:

cat /etc/passwd | awk 'BEGIN {FS=":"} $3>=500 {print $1 "\t" $3}'
查看/etc/passwd中UID大于等于500的用户名和UID。

awk命令也是一门编程语言,它还支持很多功能,比如变量、函数、流程控制等。这里不作深究。

5. sed 命令

其实,sed并不是字符截取命令。

sed是一种几乎包括在所有UNIX平台(包括Linux)的轻量级文本流编辑器。

sed主要用来对数据进行选取、替换、删除和新增。

sed和vi的区别主要在于,sed不仅仅可以编辑文件中的内容,而且可以(结合管道符)编辑命令的输出结果。

命令格式:sed [选项] ‘[动作]’ 文件名

选项:

  • -n:sed命令一般会把所有的数据都输出到屏幕,如果加入此选项,则只会把经过sed命令处理的行输出到屏幕。
  • -e:同时执行多个动作。
  • -i:将sed的修改结果直接作用于文件,而不是从屏幕输出。

动作:

  • a:追加。在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用\表示数据未完结,之后回车,输入下一行的数据。
  • c:行替换。用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需要用\表示数据未完结。
  • i:插入。在当前行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用\表示数据未完结。
  • d:删除。删除指定的行。
  • p:打印。输出指定的行。
  • s:字符串替换。用一个字符串替换另外一个字符串。格式为 “行范围s/旧字符串/新字符串/g” (和vi中的替换格式类似,/g表示全局替换,即替换行中所有匹配到的字符串)。

示例:

sed 2p /etc/issue       
将该文件中的所有内容输出的同时,将第2行再输出一遍(不会作用于文件)。

sed -n '2p' /etc/issue
只输出文件/etc/issue中的第2行(不会作用于文件)。

df -h | sed -n 2p
将df -h的执行结果中的第2行输出。

sed '2,4d' /etc/issue
删除文件中的第2行到第4行,并显示其他行。(不会作用于文件)

sed '2a this is a new line' /etc/issue
在文件的第2行后添加一行新的数据,将此效果输出。(不会作用于文件)

sed 'a this is a new line' /etc/issue
在文件的每一行之后添加一行新的数据,将此效果输出。(不会作用于文件)

sed 'i this is a new line' /etc/issue
在文件的每一行之前添加一行新的数据,将此效果输出。(不会作用于文件)

sed '2i one\
two'
/etc/issue
在文件的第2行前添加两行新的数据,将此效果输出。(不会作用于文件)

sed '3c this is a substitute of third line' /etc/issue
将文件中的第3行替换为新的数据,将此效果输出。(不会作用于文件)

sed '1s/a/AA/g' /etc/issue
将文件第1行中的所有的a替换为AA,将此效果输出。(不会作用于文件)

sed '1s/a/AA/' /etc/issue
将文件第1行中的第一个a替换为AA,将此效果输出。(不会作用于文件)

sed '1,6s/a/AA/g' /etc/issue
将第1行到第6行中所有的a替换为AA,将此效果输出。(不会作用于文件)

sed -i '1,6s/a/AA/g' /etc/issue
将第1行到第6行中所有的a替换为AA。(修改结果直接作用于文件,没有输出)

sed -e 's/AA//g;2s/n/N/g' /etc/issue
将每行的AA替换为空,同时将第2行的n替换为N,将此效果输出。(不会作用于文件)
-e表示同时执行多个动作,动作之间用分号隔开,也可用回车。