Linux文本处理工具和正则表达式

1 文本编辑工具之神VIM

1.1命令或普通(Normal)模式的基本命令

1.1.1移动光标的办法

h 或 向左箭头键(←)光标向左移动一个字符
j 或 向下箭头键(↓)光标向下移动一个字符
k 或 向上箭头键(↑)光标向上移动一个字符
l 或 向右箭头键(→)光标向右移动一个字符
[Ctrl] + [f]屏幕『向下』移动一页,相当于 [Page Down]按键 (常用)
[Ctrl] + [b]屏幕『向上』移动一页,相当于 [Page Up] 按键 (常用)
[Ctrl] + [d]屏幕『向下』移动半页
[Ctrl] + [u]屏幕『向上』移动半页
+光标移动到非空格符的下一列
-光标移动到非空格符的上一列
n那个 n 表示『数字』,例如 20 。按下数字后再按空格键,光标会向右移动这一列的 n 个字符。例如 20 则光标会向后面移动 20 个字符距离。
0 或功能键[Home]这是数字『 0 』:移动到这一列的最前面字符处 (常用)
$ 或功能键[End]移动到这一列的最后面字符处(常用)
H光标移动到这个屏幕的最上方那一列的第一个字符
M光标移动到这个屏幕的中央那一列的第一个字符
L光标移动到这个屏幕的最下方那一列的第一个字符
G移动到这个文件的最后一列(常用)
nGn 为数字。移动到这个文件的第 n 列。例如 20G 则会移动到这个文件的第 20 列(可 配合 :set nu)
gg移动到这个文件的第一列,相当于 1G 啊! (常用)
nn 为数字。光标向下移动 n 列(常用)

1.1.2搜寻与替代

/word向光标之下寻找一个名称为 word 的字符串。例如要在文件内搜寻 vbird 这个字符串, 就输入 /vbird 即可! (常用)
?word向光标之上寻找一个字符串名称为 word 的字符串。
n这个 n 是英文按键。代表『重复前一个搜寻的动作』。举例来说, 如果刚刚我们执行 /vbird 去向下搜寻 vbird 这个字符串,则按下 n 后,会向下继续搜寻下一个名称为 vbird 的字符串。如果是执行 ?vbird 的话,那么按下 n 则会向上继续搜寻名称为 vbird 的字符串!
N这个 N 是英文按键。与 n 刚好相反,为『反向』进行前一个搜寻动作。 例如 /vbird 后,按下 N 则表示『向上』搜寻 vbird 。
:n1,n2s/word1/word2/gn1 与 n2 为数字。在第 n1 与 n2 列之间寻找 word1 这个字符串,并将该字符串取代 为 word2 !举例来说,在 100 到 200 列之间搜寻 vbird 并取代为 VBIRD 则: 『:100,200s/vbird/VBIRD/g』。 (常用)
:1,$s/word1/word2/g从第一列到最后一列寻找 word1 字符串,并将该字符串取代为 word2 !(常用)
:1,$s/word1/word2/gc从第一列到最后一列寻找 word1 字符串,并将该字符串取代为 word2 !且在取代前显 示提示字符给用户确认 (confirm) 是否需要取代!(常用)

1.1.3 删除、复制与粘贴

x, X在一列字当中,x 为向后删除一个字符 (相当于 [del] 按键), X 为向前删除一个字 符(相当于 [backspace] 亦即是退格键) (常用)
nxn 为数字,连续向后删除 n 个字符。举例来说,我要连续删除 10 个字符, 『10x』。
dd删除游标所在的那一整列(常用)
nddn 为数字。删除光标所在的向下 n 列,例如 20dd 则是删除 20 列 (常用)
d1G删除光标所在到第一列的所有数据
dG删除光标所在到最后一列的所有数据
d$删除游标所在处,到该列的最后一个字符
d0那个是数字的 0 ,删除游标所在处,到该列的最前面一个字符
yy复制游标所在的那一列(常用)
nyyn 为数字。复制光标所在的向下 n 列,例如 20yy 则是复制 20 列(常用)
y1G复制光标所在列到第一列的所有数据
yG复制光标所在列到最后一列的所有数据
y0复制光标所在的那个字符到该列行首的所有数据
y$复制光标所在的那个字符到该列行尾的所有数据
p, Pp 为将已复制的数据在光标下一列贴上,P 则为贴在游标上一列! 举例来说,我目前 光标在第 20 列,且已经复制了 10 列数据。则按下 p 后, 那 10 列数据会贴在原本 的 20 列之后,亦即由 21 列开始贴。但如果是按下 P 呢? 那么原本的第 20 列会被推到变成 30 列。 (常用)
J将光标所在列与下一列的数据结合成同一列
c重复删除多个数据,例如向下删除 10 列,[ 10cj ]
u复原前一个动作。(常用)
[Ctrl]+r重做上一个动作。(常用)
.想要重复删除、重复贴上等等动作,按下小数点.就好了! (常用)
1.2 插入(Insert)或编辑模式的基本命令
i, I进入插入模式(Insert mode): i 为『从目前光标所在处插入』, I 为『在目前所在列的第一个非空格符处开始插入』。(常用)
a, A进入插入模式(Insert mode): a 为『从目前光标所在的下一个字符处开始插入』, A 为『从光标所在列的最后一个 字符处开始插入』。(常用)
o, O进入插入模式(Insert mode): 这是英文字母 o 的大小写。o 为『在目前光标所在的下一列处插入新的一列』; O 为 在目前光标所在处的上一列插入新的一列!(常用)
r, R进入取代模式(Replace mode): r 只会取代光标所在的那一个字符一次; R 会一直取代光标所在的文字,直到按下 ESC 为止;(常用)
[Esc]退出编辑模式,回到一般指令模式中(常用)
1.3 扩展命令模式基本命令
:w将编辑的数据写入硬盘文件中(常用)
:w!若文件属性为『只读』时,强制写入该文件。不过,到底能不能写入, 还是跟你对该文件 的文件权限有关啊!
:q离开 vi (常用)
:q!若曾修改过文件,又不想储存,使用 ! 为强制离开不储存文件。
:wq储存后离开,若为 :wq! 则为强制储存后离开 (常用)
ZZ这是大写的 Z 喔!若文件没有更动,则不储存离开,若文件已经被更动过,则储存后离开!
:w[filename] 将编辑的数据储存成另一个文件(类似另存新档)
:r [filename]在编辑的数据中,读入另一个文件的数据。亦即将 『filename』 这个文件内容加到游标 所在列后面
:n1,n2 w [filename]将 n1 到 n2 的内容储存成 filename 这个文件。
:! command暂时离开 vi 到指令列模式下执行 command 的显示结果!例如 『:! ls /home』即可在 vi 当中察看 /home 底下以 ls 输出的文件信息!

1.3.1 地址定界格式

##具体第#行,例如2表示第2行
#,##从左侧#表示起始行,到右侧#表示结尾行
#,+##从左侧#表示的起始行,加上右侧#表示的行数,范例:2,+3 表示2到5行
.#当前行
$#最后一行
.,$-1#当前行到倒数第二行
%#全文, 相当于1,$
/pattern/#从当前行向下查找,直到匹配pattern的第一行,即:正则表达式
/pat1/,/pat2/#从第一次被pat1模式匹配到的行开始,一直到第一次被pat2匹配到的行结束
#,/pat/#从指定行开始,一直找到第一个匹配patttern的行结束
/pat/,$#向下找到第一个匹配patttern的行到整个文件的结尾的所有行

地址定界后跟一个编辑命令

d       #删除
y 	#复制
w file  #将范围内的行另存至指定文件中
r file  #在指定位置插入指定文件中的所有内容

1.3.2 查找并替换

格式:

s/要查找的内容/替换为的内容/修饰符

说明:

  • 要查找的内容:可使用基末正则表达式模式
  • 替换为的内容:不能使用模式,但可以使用\1, \2, …等后向引用符号;还可以使用“&”引用前面查找时查找到的整个内容

修饰符:

i 	#忽略大小写
g 	#全局替换,默认情况下,每一行只替换第一次出现
gc  	#全局替换,每次替换前询问

查找替换中的分隔符/可替换为其它字符,如:#,@

1.3.3 定制vim的工作特性

扩展命令模式的配置只是对当前vim进程有效,可将配置存放在文件中持久保存

配置文件:

/etc/vimrc #全局
~/.vimrc   #个人
行号显示:set number,简写 set nu ; 取消显示:set nonumber, 简写 set nonu
忽略字符的大小写启用:set ignorecase,简写 set ic 不忽略:set noic
自动缩进启用:set autoindent,简写 set ai 禁用:set noai
复制保留格式启用:set paste 禁用:set nopaste
显示Tab和换行符 ^I 和$显示启用:set list 禁用:set nolist
高亮搜索启用:set hlsearch 禁用:set nohlsearch
语法高亮启用:syntax on 禁用:syntax off
文件格式启用windows格式:set fileformat=dos 启用unix格式:set fileformat=unix 简写 set ff=dos
设置文本宽度set textwidth=65 (vim only) set wrapmargin=15
设置光标所在行的标识线启用:set cursorline,简写 set cul 禁用:set nocursorline
加密启用: set key=password 禁用: set key=
1.4 vim的寄存器

有26个命名寄存器和1个无命名寄存器,常存放不同的剪贴版内容,可以在同一个主机的不同会话(终端窗口)间共享

寄存器名称a,b,…,z,格式:“寄存器 放在数字和命令之间

范例:
3"tyy 表示复制3行到t寄存器中,末行显示 3 lines yanked into "t

"tp 表示将t寄存器内容粘贴
未指定,将使用无命名寄存器

有10个数字寄存器,用0,1,…,9表示,0存放最近复制内容,1存放最近删除内容。当新的文本变更和删除时,1转存到2,2转存到3,以此类推。数字寄存器不能在不同会话间共享

1.5 标记和宏(macro)

ma 将当前位置标记为a,26个字母均可做标记, mb 、 mc 等等
'a 跳转到a标记的位置,实用的文档内标记方法,文档中跳跃编辑时很有用
qa 录制宏 a,a为宏的名称
q 停止录制宏
@a 执行宏 a
@@ 重新执行上次执行的宏

2 文本常见处理工具

2.1 文件内容查看命令

1 查看文本文件内容

cat 可以查看文本内容

格式:

cat [OPTION]... [FILE]...

常见选项

-E:显示行结束符$  
-A:显示所有控制符  
-n:对显示出的每一行进行编号  
-b:非空行编号  
-s:压缩连续的空行成一行  

tac 逆向显示文本内容
nl 显示行号,相当于cat -b
rev 将同一行的内容逆向显示

**2 查看非文本文件内容 **

  • hexdump
  • od
    od 即 dump files in octal and other formats
  • xxd
2.2 分页查看文件内容

more 可以实现分页查看文件,可以配合管道实现输出信息的分页

less 也可以实现分页查看文件或STDIN输出,比more更方便

查看时有用的命令包括:

  • /文本 搜索 文本
  • n/N 跳到下一个 或 上一个匹配

less 命令是man命令使用的分页器

2.3 显示文本前或后行内容

head 可以显示文件或标准输入的前面行
选项:

-c # 指定获取前#字节  
-n # 指定获取前#行  
-# 同上

tail 和head相反,查看文件或标准输入的倒数行
格式: tail [OPTION]... [FILE]...

-c # 指定获取后#字节  
-n # 指定获取后#行  
-# 同上  
-f 跟踪显示文件fd新追加的内容,常用日志监控,相当于 --follow=descriptor,当文件删除再新建同名文件,将无法继续跟踪文件  
-F 跟踪文件名,相当于--follow=name   --retry,当文件删除再新建同名文件,将可以继续跟踪文件  

tailf 类似tail –f,当文件不增长时并不访问文件

范例:

[root@centos7-E ~]#tail -0f /var/log/messages
[root@centos7-E ~]#tail -fn0 /var/log/messages
2.4 按列抽取文本

cut 命令可以提取文本文件或STDIN数据的指定列
格式

cut [OPTION]... [FILE]...

选项

-d DELIMITER: 指明分隔符,默认tab  
 -f FILEDS:  
      #: 第#个字段,例如:3  
      #,#[,#]:离散的多个字段,例如:1,3,6  
      #-#:连续的多个字段,例如:1-6 
      混合使用:1-3,7  
-c 按字符切割  
--output-delimiter=STRING指定输出分隔符
2.5 合并多个文件

paste 合并多个文件同行号的列到一行
格式 paste [OPTION]... [FILE]...

-d 分隔符:指定分隔符,默认用TAB
-s : 所有行合成一行显示

2.6 分析文本的工具

文本数据统计:wc
整理文本:sort
比较文件:diff和patch

2.6.1 收集文本统计数据
wc 命令可用于统计文件的行总数、单词总数、字节总数和字符总数
可以对文件或STDIN中的数据统计
常用选项

-l 只计数行数
-w 只计数单词总数
-c 只计数字节总数
-m 只计数字符总数
-L 显示文件中最长行的长度

2.6.2 文本排序sort
把整理过的文本显示在STDOUT,不改变原始文件
常用选项

-r 执行反方向(由上至下)整理
-R 随机排序
-n 执行按数字大小整理
-f 选项忽略(fold)字符串中的字符大小写
-u 选项(独特,unique)删除输出中的重复行
-t c 选项使用c做为字段界定符
-k # 选项按照使用c字符分隔的 # 列来整理能够使用多次

范例:第三列排序

[root@centos7-E ~]#sort -nt: -k3 /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

#取一定范围内的随机数字
[root@centos7-E ~]#seq 50 |sort -R |head -n1
8
[root@centos7-E ~]#seq 50 |sort -R |head -n1
17

2.6.3 去重uniq
uniq命令从输入中删除前后相接的重复的行
格式: uniq [OPTION]... [FILE]...

常见选项:
-c: 显示每行重复出现的次数
-d: 仅显示重复过的行
-u: 仅显示不曾重复的行

uniq常和sort 命令一起配合使用:
范例:

#统计日志访问量最多的请求
[root@centos7-E ~]#cut -d" " -f1 access_log |sort |uniq -c |sort -nr |head -3
   4870 172.20.116.228
   3429 172.20.116.208
   2834 172.20.0.222

范例:并发连接最多的远程主机IP

[root@centos7-E ~]#ss -nt |tail -n+2|tr -s ' ' : |cut -d: -f6 |sort |uniq -c |sort -nr |head -n2
      3 10.0.0.201
      3 10.0.0.1

2.6.4 比较文件

diff 命令比较两个文件之间的区别

patch 复制在其它文件中进行的改变(要谨慎使用)
适用 -b 选项来自动备份改变了的文件

cmp
范例:查看二进制文件的不同

[root@centos7-E ~]#ll /usr/bin/dir /usr/bin/ls
-rwxr-xr-x. 1 root root 117608 Aug 20  2019 /usr/bin/dir
-rwxr-xr-x. 1 root root 117608 Aug 20  2019 /usr/bin/ls
[root@centos7-E ~]#ll /usr/bin/dir /usr/bin/ls -i
477137 -rwxr-xr-x. 1 root root 117608 Aug 20  2019 /usr/bin/dir
477158 -rwxr-xr-x. 1 root root 117608 Aug 20  2019 /usr/bin/ls
[root@centos7-E ~]#diff /usr/bin/dir /usr/bin/ls
Binary files /usr/bin/dir and /usr/bin/ls differ
[root@centos7-E ~]#cmp /bin/dir /bin/ls
/bin/dir /bin/ls differ: byte 645, line 1
[root@centos7-E ~]#hexdump -s 640  -Cn5 /bin/ls
00000280  47 4e 55 00 aa                                    |GNU..|
00000285
[root@centos7-E ~]#hexdump -s 640  -Cn5 /bin/dir
00000280  47 4e 55 00 34                                    |GNU.4|
00000285

3 正则表达式

REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符

正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等

正则表达式分两类:

  • 基本正则表达式:BRE
  • 扩展正则表达式:ERE

正则表达式引擎:

采用不同算法,检查处理正则表达式的软件模块,如:PCRE(Perl Compatible Regular
Expressions)
正则表达式的元字符分类:字符匹配、匹配次数、位置锚定、分组
帮助:man 7 regex

3.1 基本正则表达式元字符

3.1.1 字符匹配

.   	  匹配任意单个字符,可以是一个汉字
[]   	  匹配指定范围内的任意单个字符,示例:[wang]   [0-9]   [a-z]     [a-zA-Z]
[^] 	  匹配指定范围外的任意单个字符,示例:[^wang]

[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号

范例:

[root@centos7-E ~]#echo google |grep 'go*gle'
google
[root@centos7-E ~]#echo ggle |grep 'go*gle'
ggle
[root@centos7-E ~]#echo goooooogle |grep 'go*gle'
goooooogle

**3.1.2 匹配次数 **

用在要指定次数的字符后面,用于指定前面的字符要出现的次数

* 		匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* 		任意长度的任意字符
\? 		匹配其前面的字符0或1次,即:可有可无
\+ 		匹配其前面的字符至少1次,即:肯定有,>=1
\{n\} 	匹配前面的字符n次
\{m,n\} 匹配前面的字符至少m次,至多n次,<=n
\{,n\}  匹配前面的字符至多n次
\{n,\}  匹配前面的字符至少n次

范例:

[root@centos7-E ~]#df |grep '^/dev/sd' |grep -o ' *[0-9]\{1,3\}%'
   6%
   1%
  18%

3.1.3 位置锚定

位置锚定可以用于定位出现的位置

^ 				行首锚定,用于模式的最左侧
$ 				行尾锚定,用于模式的最右侧
^PATTERN$ 		用于模式匹配整行
^$ 				空行
^[[:space:]]*$  空白行
\< 或 \b 		词首锚定,用于单词模式的左侧
\> 或 \b 		词尾锚定,用于单词模式的右侧
\<PATTERN\> 	匹配整个单词

范例:

[root@centos7-E ~]#grep -v '^#' /etc/fstab 
UUID=497d1f05-5848-4d94-8d6d-a664b0c2dfd7 /                       xfs     defaults        0 0
UUID=a4b9a9a5-6be9-4b65-ad9e-8cec39dccd90 /boot                   xfs     defaults        0 0
UUID=7cbb2408-35e4-4ec0-ad6c-f2f760165ad5 /date                   xfs     defaults        0 0
UUID=f415e0ec-49ba-46bb-be15-6506f01b193d swap                    swap    defaults        0 0
[root@centos7-E ~]#grep '^#' /etc/fstab 
#
# /etc/fstab
# Created by anaconda on Sat Mar 14 15:08:34 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#

3.1.4 分组其它

分组:() 将一个或多个字符捆绑在一起,当作一个整体处理,如:\(root\)+

分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, …

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

注意后向引用是引用前面的分组括号中的模式所匹配字符,而非模式本身

或者\|

范例:空行和#开头行都去掉

[root@centos7-E ~]#grep -v '^#' /etc/profile |grep -v '^$'
[root@centos7-E ~]#grep -v '^#\|^$' /etc/profile
[root@centos7-E ~]#grep -v '^\(#\|$\)' /etc/profile
[root@centos7-E ~]#grep  '^[^#]' /etc/profile

范例:

[root@centos7-E ~]#echo ooo |grep 'o\{3\}'
ooo
[root@centos7-E ~]#echo oooo |grep 'o\{3\}'
oooo

[root@centos7-E ~]#echo abcabcabc |grep '\(abc\)\{3\}'
abcabcabc
3.2 扩展正则表达式

3.2.1 字符匹配元字符

. 		任意单个字符 
[wang] 		指定范围的字符
[^wang] 	不在指定范围的字符
[:alnum:] 	字母和数字
[:alpha:] 	代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 	小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 	大写字母
[:blank:] 	空白字符(空格和制表符)
[:space:] 	水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 	不可打印的控制字符(退格、删除、警铃...)
[:digit:] 	十进制数字
[:xdigit:]	十六进制数字
[:graph:] 	可打印的非空白字符
[:print:] 	可打印字符
[:punct:] 	标点符号

范例:取出IP地址

[root@centos7-E ~]#ifconfig eth0 |grep -Eo ' ([0-9]{1,3}\.){3}[0-9]{1,3}' |head -1
 10.0.0.208

3.2.2 次数匹配

*   	匹配前面字符任意次
? 	0或1次
+ 	1次或多次
{n} 	匹配n次
{m,n} 	至少m,至多n次

3.2.3 位置锚定

^ 	行首
$ 	行尾
\<, \b  语首
\>, \b  语尾

3.2.4 分组其它

() 			分组
后向引用:		\1, \2, ...
| 			或者
a|b 			#a或b
C|cat 			#C或cat
(C|c)at 		#Cat或cat

范例:显⽰三个⽤户root、 cui、 www的UID和默认shell

[root@centos7-E ~]#egrep "^(root|cui|www)" /etc/passwd |cut -d: -f1,3,7
root:0:/bin/bash
cui:1000:/bin/bash
www:1004:/bin/bash

4 文本处理三剑客

grep :命令主要对文本的(正则表达式)行基于模式进行过滤
sed:stream editor,文本编辑工具
awk:Linux上的实现gawk,文本报告生成器

4.1 文本处理三剑客之 grep

grep: Global search REgular expression and Print out the line

作用:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行

模式:由正则表达式字符及文本字符所编写的过滤条件

格式:

grep [OPTIONS] PATTERN [FILE...]
# PATTERN可以写成正则表达式

常见选项:

--color=auto   		 到的文本着色显示
-m # 		 	 配#次后停止
-v 			 显示不被pattern匹配到的行
-i 			 忽略字符大小写
-n 			 显示匹配的行号
-c 			 统计匹配的行数
-o 			 仅显示匹配到的字符串
-q 			 静默模式,不输出任何信息
-A 			 after, 后#行
-B 			 before, 前#行
-C 			 context, 前后各#行
-e 			 实现多个选项间的逻辑or关系,如:grep –e ‘cat ’ -e ‘dog’ file
-w 			 匹配整个单词  #除了数字字母下划线,其他符号都是分界符
-E 			 使用ERE,相当于egrep
-F 			 相当于fgrep,不支持正则表达式
-f file 	 	 据模式文件处理
grep [OPTIONS] PATTERN [FILE...]
-r 	 		 递归目录,但不处理软链接
-R 	 		 递归目录,但处理软链接

范例:

[root@centos7-E ~]#ifconfig | grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}'
inet 10.0.0.208  netmask 255.255.255.0  broadcast 10.0.0.255
inet 127.0.0.1  netmask 255.0.0.
inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
[root@centos7-E ~]#ifconfig | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'
10.0.0.208
255.255.255.0
10.0.0.255
127.0.0.1
255.0.0.0
192.168.122.1
255.255.255.0
192.168.122.255
[root@centos7-E ~]#ifconfig eth0| grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'
10.0.0.208
255.255.255.0
10.0.0.255
[root@centos7-E ~]#ifconfig eth0| grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' |head -1
10.0.0.208

范例:

[root@centos7-E ~]#grep root /etc/passwd &> /dev/null
[root@centos7-E ~]#grep -q root /etc/passwd
[root@centos7-E ~]#echo $?  #验证上一条命令是否执行成功
0                           #0即成功
[root@centos7-E ~]#grep -q ROOT /etc/passwd
[root@centos7-E ~]#echo $?
1                           #1即失败

[root@centos7-E ~]#grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
[root@centos7-E ~]#grep -nA2 root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
2-bin:x:1:1:bin:/bin:/sbin/nologin
3-daemon:x:2:2:daemon:/sbin:/sbin/nologin
--
10:operator:x:11:0:operator:/root:/sbin/nologin
11-games:x:12:100:games:/usr/games:/sbin/nologin
12-ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

#查找包含root且包含bash的行
[root@centos7-E ~]#grep root /etc/passwd |grep bash  
root:x:0:0:root:/root:/bin/bash
4.2 文本处理三剑客之 sed

4.2.1 sed 工作原理

sed 即 stream EDitor,和 vi 不同,sed是行编辑器

Sed是从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,直到最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(Pattern Space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现有卡顿的现象,这是因为vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快

4.2.2 sed 基本用法

格式:

sed [option]... 'script;script;...' inputfile...

常用选项:

-n 不输出模式空间内容到屏幕,即不自动打印  
-e 多点编辑  
-f /PATH/SCRIPT_FILE 从指定文件中读取编辑脚本
-r, -E 使用扩展正则表达式
-i.bak 备份文件并原处编辑

script格式:

'地址命令'

地址格式:

1. 不给地址:对全文进行处理
2. 单地址:
   #:指定的行,$:最后一行
   /pattern/:被此处模式所能够匹配到的每一行
3. 地址范围:
   #,#   #从#行到第#行,3,6 从第3行到第6行
   #,+#   #从#行到+#行,3,+4 表示从3行到第7行
   /pat1/,/pat2/
   #,/pat/
4. 步进:~
     1~2 奇数行
     2~2 偶数行

命令:

p 打印当前模式空间内容,追加到默认输出之后
Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a [\\]text 在指定行后面追加文本,支持使用\n实现多行追加
i [\\]text 在行前面插入文本
c [\\]text 替换行为单行或多行文本
w /path/file 保存模式匹配的行至指定文件
r /path/file 读取指定文件的文本至模式空间中匹配到的行后
= 为模式空间中的行打印行号
! 模式空间中匹配行取反处理

s/pattern/string/修饰符 查找替换,支持使用其它分隔符,可以是其它形式:s@@@,s###
替换修饰符:
g 行内全局替换
p 显示替换成功的行
w   /PATH/FILE 将替换成功的行保存至文件中
I,i   忽略大小写

范例:

[root@centos7 ~]#sed ''
hello
hello
world
world
^C
[root@centos7 ~]#sed '' /etc/issue
\S
Kernel \r on an \m

[root@centos7 ~]#sed 'p' /etc/issue
\S
\S
Kernel \r on an \m
Kernel \r on an \m


[root@centos7 ~]#sed -n '' /etc/issue
[root@centos7 ~]#sed -n 'p' /etc/issue
\S
Kernel \r on an \m

[root@centos7 ~]#sed -n '1p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@centos7 ~]#if
if         ifconfig   ifenslave  ifup       
ifcfg      ifdown     ifstat     
[root@centos7 ~]#if
if         ifconfig   ifenslave  ifup       
ifcfg      ifdown     ifstat     
[root@centos7 ~]#ifconfig eth0 |sed '2p'
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.7  netmask 255.255.255.0  broadcast 10.0.0.255
        inet 10.0.0.7  netmask 255.255.255.0  broadcast 10.0.0.255
        ether 00:0c:29:4a:78:9b  txqueuelen 1000  (Ethernet)
        RX packets 20071  bytes 9946274 (9.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5133  bytes 556858 (543.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@centos7 ~]#ifconfig eth0 |sed -n '2p'
        inet 10.0.0.7  netmask 255.255.255.0  broadcast 10.0.0.255
[root@centos7 ~]#sed -n '$p' /etc/pa
pam.d/   passwd   passwd-  
[root@centos7 ~]#sed -n '$p' /etc/passwd
qing:x:1004:1004::/home/qing:/bin/bash

[root@centos7 ~]#df | sed -n '/^\/dev\/sd/p'
/dev/sda2      104806400 1907652 102898748   2% /
/dev/sda5       52403200   66116  52337084   1% /data
/dev/sda1        1038336  144220    894116  14% /boot

[root@centos7 data]#seq 10 | sed -n '3,6p'
3
4
5
6
[root@centos7 data]#seq 10 | sed -n '3,+4p'
3
4
5
6
7
[root@centos7 data]#seq 10 |sed -n '1~2p'
1
3
5
7
9
[root@centos7 data]#seq 10 |sed -n '2~2p'
2
4
6
8
10
[root@centos7 data]#seq 10 |sed -n '1~3p'
1
4
7
10
[root@centos7 data]#seq 10 |sed '5aabc'
1
2
3
4
5
abc
6
7
8
9
10
[root@centos7 data]#seq 10 |sed '5a\   abc'
1
2
3
4
5
   abc
6
7
8
9
10
[root@centos7 data]#seq 10 |sed '5a\   abc\n   123'
1
2
3
4
5
   abc
   123
6
7
8
9
10
[root@centos7 data]#seq 10 |sed '5i\   abc\n   123'
1
2
3
4
   abc
   123
5
6
7
8
9
10
[root@centos7 data]#seq 10 |sed '5c\   abc'
1
2
3
4
   abc
6
7
8
9
10
[root@centos7 data]#seq 10 |sed -e '5i\abc' -e '5a\123'
1
2
3
4
abc
5
123
6
7
8
9
10

#删除所有以#开头的行
[root@centos7 data]#sed -n '/^#/d' /etc/fstab 
UUID=33eaf474-e635-42e1-abf4-3b2cdc47008e /                       xfs     defaults        0 0
UUID=00958e26-8808-4f48-afdc-c50d22b1b515 /boot                   xfs     defaults        0 0
UUID=9e8b2e6f-5f43-47e0-bb6c-04aab9c60b54 /data                   xfs     defaults        0 0
UUID=7147085c-837a-4dd2-a047-ea7693a5729c swap                    swap    defaults        0 0
#只显示非#开头的行
[root@centos7 ~]#sed -n '/^#/!p' /etc/fstab 

UUID=33eaf474-e635-42e1-abf4-3b2cdc47008e /                       xfs     defaults        0 0
UUID=00958e26-8808-4f48-afdc-c50d22b1b515 /boot                   xfs     defaults        0 0
UUID=9e8b2e6f-5f43-47e0-bb6c-04aab9c60b54 /data                   xfs     defaults        0 0
UUID=7147085c-837a-4dd2-a047-ea7693a5729c swap                    swap    defaults        0 0

#修改网卡配置
[root@centos8 ~]#sed -Ei.bak '/^GRUB_CMDLINE_LINUX/s/(.*)(")$/\1net.ifnames=0\2/' /etc/default/grub

范例:取IP 地址

[root@centos8 ~]#ifconfig eth0 |sed -nr "2s/[^0-9]+([0-9.]+).*/\1/p"
10.0.0.8
[root@centos8 ~]#ifconfig eth0 | sed -rn '2s/^[^0-9]+([0-9.]+) .*$/\1/p'
10.0.0.8   #此写法更通用
[root@centos8 ~]#ifconfig eth0 | sed -n '2s/^.*inet //p' | sed -n 's/
netmask.*//p'
10.0.0.8
[root@centos8 ~]#ifconfig eth0 | sed -n '2s/^.*inet //;s/ netmask.*//p'
10.0.0.8
[root@centos8 ~]#ifconfig eth0 | sed -rn '2s/(.*inet )([0-9].*)(
netmask.*)/\2/p'
10.0.0.8

范例:将非#开头的行加#

[root@centos7 ~]#sed -rn 's/^[^#]/#/p' /etc/fstab 
#UID=33eaf474-e635-42e1-abf4-3b2cdc47008e /                       xfs     defaults        0 0
#UID=00958e26-8808-4f48-afdc-c50d22b1b515 /boot                   xfs     defaults        0 0
#UID=9e8b2e6f-5f43-47e0-bb6c-04aab9c60b54 /data                   xfs     defaults        0 0
#UID=7147085c-837a-4dd2-a047-ea7693a5729c swap                    swap    defaults        0 0
[root@centos7 ~]#sed -rn 's/^[^#](.*)/#\1/p' /etc/fstab 
#UID=33eaf474-e635-42e1-abf4-3b2cdc47008e /                       xfs     defaults        0 0
#UID=00958e26-8808-4f48-afdc-c50d22b1b515 /boot                   xfs     defaults        0 0
#UID=9e8b2e6f-5f43-47e0-bb6c-04aab9c60b54 /data                   xfs     defaults        0 0
#UID=7147085c-837a-4dd2-a047-ea7693a5729c swap                    swap    defaults        0 0
[root@centos7 ~]#sed -rn '/^#/!s@^@#@p' /etc/fstab 
#
#UUID=33eaf474-e635-42e1-abf4-3b2cdc47008e /                       xfs     defaults        0 0
#UUID=00958e26-8808-4f48-afdc-c50d22b1b515 /boot                   xfs     defaults        0 0
#UUID=9e8b2e6f-5f43-47e0-bb6c-04aab9c60b54 /data                   xfs     defaults        0 0
#UUID=7147085c-837a-4dd2-a047-ea7693a5729c swap                    swap    defaults        0 0

范例:将#开头的行删除#

[root@centos8 ~]#sed -ri.bak '/^#/s/^#//' /etc/fstab

范例:取分区利用率

[root@centos7 ~]#df |sed -nr '/^\/dev\/sd/s/.* ([0-9]+)%.*/ \1/p'
 2
 1
 14

范例:修改内核参数

[root@centos8client ~]# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto resume=UUID=234bb9f7-f0fb-4f7e-8760-9b9233e3c5ad rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
[root@centos8client ~]# sed -nr '/^GRUB_CMDLINE_LINUX/s/"$/ net.ifname=0"/p' /etc/default/grub
GRUB_CMDLINE_LINUX="crashkernel=auto resume=UUID=234bb9f7-f0fb-4f7e-8760-9b9233e3c5ad rhgb quiet net.ifname=0"

[root@centos8 ~]#sed -rn '/^GRUB_CMDLINE_LINUX=/s@(.*)"$@\1 net.ifnames=0"@p'
/etc/default/grub
GRUB_CMDLINE_LINUX="crashkernel=auto resume=UUID=a0efb2bb-8227-4317-a79d-
0a70d515046c rhgb quiet net.ifnames=0"

范例:修改网卡名称

[root@centos8 ~]#sed -ri '/^GRUB_CMDLINE_LINUX=/s@"$@ net.ifnames=0"@'
/etc/default/grub

#centos7,8
[root@centos8 ~]#grub2-mkconfig -o /boot/grub2/grub.cfg

#ubuntu
[root@ubuntu ~]#grub-mkconfig -o /boot/grub/grub.cfg

范例:引用变量

[root@centos8 ~]#echo|sed "s/^/$RANDOM.rmvb/"
5242.rmvb
[root@centos8 ~]#echo|sed 's/^/$RANDOM.rmvb/'
$RANDOM.rmvb
[root@centos8 ~]#echo|sed 's/^/'''$RANDOM'''.rmvb/'

4.2.3 sed 高级用法

sed 中除了模式空间,还另外还支持保持空间(Hold Space),利用此空间,可以将模式空间中的数据,临时保存至保持空间,从而后续接着处理,实现更为强大的功能。
常见的高级命令

  • P 打印模式空间开端至\n内容,并追加到默认输出之前
  • h 把模式空间中的内容覆盖至保持空间中
  • H 把模式空间中的内容追加至保持空间中
  • g 从保持空间取出数据覆盖至模式空间
  • G 从保持空间取出内容追加至模式空间
  • x 把模式空间中的内容与保持空间中的内容进行互换
  • n 读取匹配到的行的下一行覆盖至模式空间
  • N 读取匹配到的行的下一行追加至模式空间
  • d 删除模式空间中的行
  • D 如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本,并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间不包含换行符,则会像发出d命令那样启动正常的新循环
    范例:
sed -n 'n;p' FILE
sed '1!G;h;$!d' FILE
sed ‘N;D’FILE
seq 10 |sed  '3h;9G;9!d'
sed '$!N;$!D' FILE
sed '$!d' FILE
sed ‘G’ FILE
sed ‘g’ FILE
sed ‘/^$/d;G’ FILE
sed 'n;d' FILE 
sed -n '1!G;h;$p' FILE
4.3 文本处理三剑客之 awk

跳转链接:Linux进阶_文本处理工具AWK

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值