第5节 Linux文本处理工具与正则表达式
文本处理工具1 (前一章59:00)
文本三剑客
grep
sed
awk
抽取文本的工具
cat
cat -n /data/f1 # -n:对显示出的每一行进行编号
cat -b /data/f1 # -b:非空行编号
cat -sn /data/f1 # -s:压缩连续的空行成一行
cat -E /data/f1 # -E:显示行结束符$
cat -A /data/f1 #-A:显示所有控制符
以下命令会产生不同效果
cat < f1 > f1 # 显示结果清空f1内容
cat < f1 > f2 # f2显示结果为f1内容
cat < f1 >> f1 # 追加无数个f1文件内容
01. 文本处理工具1
tac
tac命令用于将文件已行为单位的反序输出,即第一行最后显示,最后一行先显示。
#### rev
rev命令将文件中的每行内容以字符为单位反序输出,即第一个字符最后输出,最后一个字符最先输出,依次类推。
more less
分页查看文件
head
head -n 3 file # 显示前3行 默认前10行
echo abcdefg |head -c2 #取前两个字符
cat /dev/urandom |tr -dc 'a-zA-Z0-9_'|head -c12 #取随机12字符
tail
tail -f -n 3 f1 # 跟踪显示文件新追加的内容,常用日志监控
删除跟踪的文件不会有变化 ;-F 跟踪文件名称,可以继续跟踪
tailf 类似tail –f,当文件不增长时并不访问文件
ifconfig eth0|head -2|tail -1
cut (00:18:00)
cut -d: -f1,3 /etc/passwd # 以:为分隔符取文件第1,3列
cut -d: -f1,3,5-7 /etc/passwd
df |cut -c44-47 # 取分区利用率
df |tr -s ' ' :|cut -d: -f5|tr -d %
dr |tr -s " " %|cut -d% -f5
取ip地址:
ifconfig eth0 | head -2|tail -1|tr -s ' ' :|cut -d: -f3
ifconfig eth0 | head -2|tail -1|tr -s ' '|cut -d" " -f3
ifconfig eth0 | head -2|tail -1|cut -dt -f2|cut -dn -f1
ifconfig eth0 | head -2|tail -1|cut -d: -f2|tr -dc '[0-9].'
ifconfig eth0 | head -2|tail -1| tr -dc '[0-9]. ' |tr -s ' ' |cut -d" " -f2
cut -d: -f1,3 --output-delimiter=+ /etc/passwd #指定输出分隔符
paste (00:51:00)
横向合并文件
paste f1 f2
-d 分隔符:指定分隔符,默认用TAB
paste -d":" f1 f2
-s : 所有行合成一行显示
paste -s -d: f1 f2
wc 文本数据统计
wc story.txt
39 237 1901 story.txt
行数 字数 字节数
常用选项
-l 只计数行数
-w 只计数单词总数
-c 只计数字节总数
-m 只计数字符总数
-L 显示文件中最长行的长度
取远程主机连接的ip地址(1:05:00)
ss -nt|tr -s ' ' : |cut -d: -f6|tr -dc '[0-9].\n'
ss -nt |cut -d: -f2|tr -s " " |cut -d" " -f 2
ss -nt |tr -dc '0-9 .\n:' |tr -s " " :|cut -d: -f6
统计单词个数
cut -c2-5 /usr/share/dict/words
cat /etc/profile|tr -sc 'a-zA-Z' '\n'|wc -l
02. 文本处理工具2
sort
sort -t: -k3 -n /etc/passwd
常用选项
-r 执行反方向(由上至下)整理
-R 随机排序
-n 执行按数字大小整理
-f 选项忽略(fold)字符串中的字符大小写
-u 选项(独特,unique)删除输出中的重复行
-t c 选项使用c做为字段界定符
-k X 选项按照使用c字符分隔的X列来整理能够使用多次
df|tr -s ' ' "%"|cut -d% -f5|sort -nr|head -n1
df|tr -s ' ' "%"|cut -d% -f5|sort -n|tail -n1
uniq (00:19:00)
从输入中删除前后相接的重复的行
uniq [OPTION]… [FILE]…
-c: 显示每行重复出现的次数
-d: 仅显示重复过的行
-u: 仅显示不曾重复的行
注:连续且完全相同方为重复
cut -d " " -f1 /var/log/httpd/access_log |sort |uniq -c|sort -nr|head
一些应用命令
取两个文件交集与并集(00:31:00)
cat f1 f2|sort |uniq -d # 显示交集
cat f1 f2|sort |uniq -u # 显示不同
cat f1 f2|sort -u # 并集
diff 比较文件
diff foo.conf foo2.conf
-u :输出“统一的(unified)”diff格式文件
patch
diff 命令的输出被保存在一种叫做“补丁”的文件中
使用 -u 选项来输出“统一的(unified)”diff格式文件,最适用于补丁文件
diff -u foo.conf foo2.conf > foo.patch
patch -b foo.conf foo.patch
grep(00:46:00)
grep root /etc/passwd
ifconfig eth0|grep netmask # 显示不被pattern匹配到的行
ss -nt|grep ESTAB
df|grep /dev/sd |tr -s ' ' %|cut -d% -f5|sort -nr
grep `whoami` /etc/passwd
nmap -v -sp 192.168.34.0/24 |grep -B1 up |grep report |cut -d " " -f5 > iplist.txt #演示扫描在线ip地址
grep -e root -e wang /etc/passwd #过滤逻辑or关系
grep root /etcpasswd |grep bash # 过滤逻辑and关系
grep -w root /etc/passwd # 匹配单词root,如果不加-w 带root的字符串都会匹配到
grep -f f1 f2 #可以实现取f1 f2交集
grep [OPTIONS] PATTERN [FILE…]
命令选项
–color=auto: 对匹配到的文本着色显示
-v: 显示不被pattern匹配到的行
-i: 忽略字符大小写
-n:显示匹配的行号
-c: 统计匹配的行数
-o: 仅显示匹配到的字符串
-q: 静默模式,不输出任何信息
-A #: after, 后#行
-B #: before, 前#行
-C #:context, 前后各#行
-e:实现多个选项间的逻辑or关系
grep –e ‘cat ’ -e ‘dog’ file
-w:匹配整个单词
-E:使用ERE
-F:相当于fgrep,不支持正则表达式
-f file: 根据模式文件处理
03. 正则表达式
正则表达式: Regular Expressions 简写为regex 由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能
程序支持:grep,sed,awk,vim, less,nginx,varnish等
分两类:
基本正则表达式:BRE
扩展正则表达式:ERE
grep -E, egrepman 7 regex
表示方式
元字符 | 定义 |
---|---|
. | 匹配任意一个字符,除了换行符 |
* | 表示前边字符有0个或多个; ".*"表示任意一个字符有0个或多个,也就是能匹配任意的字符 |
^ | 行首 |
$ | 行尾 |
[ ] | []内任意单一字符 |
[^] | 除[]内任意单一字符 |
\ | 表示是转义字符 |
\+ | +前面字符重复一次以上不确定次数 |
? | ?前面字符重复0或1次 |
\{n\} | 前面字符重复n次 |
\{n,\} | 前面字符重复n次以上 |
\{m,n\} | 前面字符重复m次和n次之间 |
grep "[^123]" /etc/passwd
ifconfig eth0|grep netmask|grep '[[:digit:].]'
grep "gooo*gle" f1 #o至少出现2次
grep "go\?gle" f1 #o出现0次或1次
grep "go\{2,14\}gle" #o出现2-14次
ifconfig |grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" # ip简单表达
位置锚定(00:33:00)
^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
\< 或 \b 词首锚定,用于单词模式的左侧
\> 或 \b 词尾锚定,用于单词模式的右侧
\<PATTERN\> 匹配整个单词
grep "^google$" f1
grep -v "^$" f1 # 非空行显示
grep -v "^#" /etc/fstab |grep -v "^$"
grep "\<root\>" /etc/passwd
分组和后项引用 ( )(00:46:00)
后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
grep "\(abc\)\{3\}" f1
grep "\(abc\).*\1"
grep "\(abc\).*\(xyz\).*\2" f1
grep "^\(a\|b\)" /etc/passwd # a开头或b开头
ifconfig eth0 |grep -o "\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}" |head -1
04. 扩展正则表达式和Vim
egrep及扩展的正则表达式
字符匹配:
. 任意单个字符
[] 指定范围的字符
[^] 不在指定范围的字符
*
匹配前面字符任意次
?
0或1次
+
1次或多次
{m} 匹配m次
{m,n} 至少m,至多n次
位置锚定:
^ 行首
$ 行尾
\<, \b 语首
\>, \b 语尾
分组:
()
后向引用:\1, \2, ...
或者:
a|b a或b
C|cat C或cat
(C|c)at Cat或cat
例子:(00:10:00)
echo "/etc/rc.d/init.d/functions/" |grep -Eo ".*[^/]"|grep -Eo "[^/]+$" # 使用egrep取出/etc/rc.d/init.d/functions中其基名
(00:26:00)
利用扩展正则表达式分别表示0-9、10-99、100-199、200-249、250-255
(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])
显示ifconfig命令结果中所有IPv4地址
ifconfig | grep -Eo "(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
vim (00:43:30)
三种主要模式:
命令(Normal)模式:默认模式,移动光标,剪切/粘贴文本
插入(Insert)或编辑模式:修改文本
扩展命令(extended command )模式:保存,退出等
命令模式 | |
---|---|
i | insert,在光标所在处输入 |
I | 在当前光标所在行的行首输入 |
a | append,在光标所在处后面输入 |
A | 在当前光标所在行的行尾输入 |
o | 在当前光标所在行的下方打开一个新行 |
O | 在当前光标所在行对上方打开一个新行 |
ZZ | 保存退出 |
ZQ | 不保存退出 |
h|jkl | h:左 l:右 k:上 j:下 #COMMAND: 跳转由#指定的个数的字符 |
w e b | w:下一个单词的词首 e:当前或下一个单词的词尾 b:当前或前一个单词的词首 |
H M L | 当前页跳转 H:页首 M:页中间行: L:页底 |
zt | 将光标所在当前行移到屏幕顶端 |
zz | 将光标所在当前行移到屏幕中间 |
zb | 将光标所在当前行移到屏幕底端 |
^ | 跳转至行首的第一个非空白字符 |
0 | 跳转至行首 |
$ | 跳转至行尾 |
#G | 跳转至由#指定行 |
G | 最后一行 |
1G,gg | 第一行 |
) ( | ):下一句 (:上一句 |
} { | {: 上一段 }:下一段 |
Ctrl+f | 向文件尾部翻一屏 |
Ctrl+b | 向文件首部翻一屏 |
Ctrl+d | 向文件尾部翻半屏 |
Ctrl+u | 向文件首部翻半屏 |
扩展命令模式 | |
---|---|
:q | 退出 |
:q! | 强制退出,丢弃做出的修改 |
:wq | 保存退出 |
:x | 保存退出 |
:w | 写(存)磁盘文件 |
r filename | 读文件内容到当前文件中 |
w filename | 将当前文件内容写入另一个文件 |
!command | 执行命令 |
r!command(!!command) | 读入命令的输出 |
查找
/PATTERN:从当前光标所在处向文件尾部查找
?PATTERN:从当前光标所在处向文件首部查找
n:与命令同方向
N:与命令反方向
s: 在扩展模式下完成查找替换操作
格式:s/要查找的内容/替换为的内容/修饰符
要查找的内容:可使用模式
替换为的内容:不能使用模式,但可以使用\1, \2, …等后向引用符号;还可
以使用“&”引用前面查找时查找到的整个内容
修饰符:
i: 忽略大小写
g: 全局替换;默认情况下,每一行只替换第一次出现
gc:全局替换,每次替换前询问
查找替换中的分隔符/可替换为其它字符,例如
s@/etc@/var@g
s#/boot#/#i
shell脚本:
包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
算术运算
bash中的算术运算:help let
+, -, *, /, %取模(取余), **(乘方)
实现算术运算:
(1) let var=算术表达式
(2) var=
[
算
术
表
达
式
]
(
3
)
v
a
r
=
[算术表达式] (3) var=
[算术表达式](3)var=((算术表达式))
(4) var=KaTeX parse error: Unexpected character: '' at position 73: …o ‘算术表达式’ | bc ̲ 乘法符号有些场景中需要转义,…RANDOM(0-32767)
echo
[
[
[RANDOM%50] :0-49之间随机数
逻辑运算
非:!
! 1 = 0
! true
! 0 = 1
! false
短路运算
短路与
第一个为0,结果必定为0
第一个为1,第二个必须要参与运算
短路或
第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
异或:^
异或的两个值,相同为假,不同为真
脚本练习
编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到
/root/etcYYYY-mm-dd中
#!/bin/bash
echo "Backup is begin..."
sleep 1
cp -av /etc/ /data/etc`date +%F`
echo "Backup is finished"
编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
#!/bin/bash
echo The max disk per is `df|grep /dev/sd|tr -s ' '|cut -d ' ' -f5|sort -nr|head -n 1`
编写脚本nologin.sh和login.sh,实现禁止和允许普通用户登录系统
nologin.sh
#!/bin/bash
echo Now nologin
touch /etc/nologin
#!/bin/bash
echo Now login
rm -rf /etc/nologin