文本三剑客
一、grep(文本内容过滤器)
-
两种形式
- grep [option] pattern [file1,file2,…]
- some command | grep [option] pattern
-
option说明:
- -i 忽略大小写
- -c 只输出匹配行的数量
- -n 显示行号
- -r 递归搜索
- -E 支持拓展正则表达式
- -w 匹配整个单词
- -l 只列出匹配的文件名
- -F 不支持正则,按字符串字面意思进行匹配
-
例子:
# 取出文件中包含“root”的行
grep root 文件名
# 取出命令结果包含“mysql”的行
命令 | grep mysql
# 取出文件中包含当前登录用户名的行
grep "$USER" 文件名
# 取出文件中包含“Root”的行(忽略Root大小写)
grep -i Root 文件名
# 取出文件中符合正则:“^k”的行(以k开头)
grep '^k' 文件名
二、sed(文本内容编辑)
-
两种形式
- sed [option] “pattern command” file
- some command | sed [option] “pattern command”
-
option说明:
- -n 只打印模式匹配的行
- -f 加载存放动作的文件
- -r 支持拓展正则
- -i 直接修改文件
-
pattern模式
5
只处理第5行5,10
只处理第5到第10行/pattern1/
只处理能匹配pattern1的行/pattern1/,/pattern2/
只处理从匹配pattern1的行到匹配pattern2的行
-
command命令
- 查询
- p 打印
- 新增
- a 在匹配行后新增
- i 在匹配行前新增
- r 外部文件读入,行后新增
- w 匹配行写入外部文件
- 删除
- d
- 替换
- s/old/new/ 只修改匹配行中第一个old
- s/old/new/g 修改匹配行中所有old
- s/old/new/ig 忽略大小写
- 查询
例子:
# 打印文件的第二行
sed -n '2 p' 文件名
cat 文件名 | sed -n '2 p'
# 打印文件的第4-7行
sed -n '4,,7 p' 文件名
# 打印文件包含“root”的行
sed -n '/root/ p' 文件名
# 打印文件以“root”开头的行
sed -n '/^root/ p' 文件名
# 打印文件以“/sbin/nologin”结尾的行
sed -n '/\/sbin\/nologin$/ p' 文件名
# 在包含‘ntp’的行后面增加‘文本内容’(修改文件一定要加-i,不然不会真的对文件进行修改)
sed -i '/ntp/ a 文本内容' 文件名
# 在包含‘root’的行的后面添加test.txt的内容
sed -i '/root/ r test.txt' 文件名
# 将包含bash的行写入新文件路径的文件中
sed -i '/bash/ w 新文件路径' 文件名
# 将上面''中的内容放到sed文件中,使用此命令读取并执行sed文件的操作
sed -i -f sed文件 文件名
# 删除文件中所有包含#的行
sed -i '/#/ d' 文件名
# 删除文件中所有包含#的行和空行
sed -ri '/#|^$/ d' 文件名
# 将文件中的每行的第一个bash改为BASH
sed -i 's/bash/BASH/' 文件名
# 将文件中的所有bash改为BASH
sed -i 's/bash/BASH/g' 文件名
# 将文件中包含‘/sbin/nologin’的行中所有bin改为BIN
sed -i '/\/sbin\/nologin/ s/bin/BIN/g' 文件名
# 将文件中包含‘Port 22’的行整行修改为‘Port 2200’
sed -i '/Port 22/ c Port 2200' 文件名
三、awk(处理数据)
- 两种形式
- awk ‘BEGIN{} pattern {commands} END{}’ file
- some command | awk ‘BEGIN{} pattern {commands} END{}’
格式 | 含义 |
---|---|
BEGIN{} | 处理数据之前执行,只执行一次 |
pattern | 匹配模式 |
{commands} | 处理的命令 |
END{} | 处理数据之后执行,只执行一次 |
3.1 内置变量
内置变量 | 含义 |
---|---|
$0 | 整行内容 |
$1~$n | 当前行的第1~n个字段 |
NF(Number Field) | 当前行字段数 |
NR(Number Row) | 当前行行号,从1开始 |
FS(Field Separator) | 输入字段分割符,默认为空格或tab键 |
RS(Row Separator) | 输入行分割符,默认为回车符 |
OFS(Output Field Separator) | 输出字段分割符,默认为空格 |
ORS(Output Row Separator) | 输出行分割符,默认为回车符 |
3.2 printf格式符
%s
字符串
%d
十进制数字
%f
浮点数
3.3 修饰符
+
右对齐
-
左对齐
3.4 匹配方式
- 正则表达式匹配
- /正则表达式/
- 关系运算
- <、<=、>、>=、==、!=
- 正则匹配:-、!-
- 布尔运算
- ||
- &&
- !
- 算术运算
- +、-、*、/、%、^、**
- ++i、i–
3.5 流程控制语句
3.5.1 if
if (条件)
else if
动作
else
动作
3.5.2 for
for (i=0;i<=100;i++)
{
动作
}
3.5.3 while
while (条件)
{
动作
}
3.6 函数
- length(str)
- tolower(str)
- toupper(str)
例子:
# 打印出文件的第一列
awk '{print $1}' 文件名
# 打印出文件每一行的字段数
awk '{print NF}' 文件名
# 打印出文件每一行的最后一列
awk '{print $NF}' 文件名
# 将文件以“:”分割并打印出每三列
awk -F":" '{print $3}' 文件名
awk 'BEGIN{FS=":"} {print $3}' 文件名
# 将文件以“:”分割并打印出包含“root”的行的倒数第二列
awk -F":" '/root/ {print $(NF-1)}' 文件名
# 将文件以“:”分割并打印出以“ntp”开始到以“aaron”结束的行的第一列
awk -F":" '/^ntp/,/^aaron/ {print $1}' 文件名
# 将文件以“:”分割并打印出包含三个w的行的第一列
awk 'BEGIN{FS=":"} /W{3}/ {print $1}' 文件名
# 将文件以“:”分割并打印出第5行到第10行的第一列
awk -F":" 'NR >= 5 && NR <= 10 {print $1}' 文件名
awk -F":" 'NR==5,NR==10 {print $1}' 文件名
# 每处理一行给count+1,最后处理完成后打印count变量
awk -F":" '{count++} END{print count}' 文件名
# 将“$1, $NF”按照“%-20s %30s\n”的格式填充打印
# (20和30代表当前字段占20和30个长度,不够的用空格补;-代表第一列左对齐)
awk -F":" '{printf "%-20s %30s\n", $1, $NF}' 文件名
# 给上面的结果加上表头
awk -F":" 'BEGIN{printf "%-20s %30s\n","USER","TERMINAL"} {printf "%-20s %30s\n", $1, $NF}' 文件名
# 给上面的结果最后一行加上TOTAL和对应的数量
awk -F":" 'BEGIN{printf "%-20s %30s\n","USER","TERMINAL"} {count++; printf "%-20s %30s\n", $1, $NF} END{printf "%-20s %30s\n","TOTAL",count}' 文件名
# 上面的表达式太长了,我们可以放到文件中来执行(要注意awk文件中的pattern要放在commamds中)
awk -F":" -f test.awk 文件名
awk文件的例子:
BEGIN{
printf "%-20s%-30s\n", "User", "Terminal"
}
{
if (NR >=1 && NR <= 10)
{
count++;
printf "%-20s%-30s\n", $1, $NF
}
}
END{
printf "%-20s%-30s\n", "Total", count
}