grep 、sed、awk被称为linux中的"三剑客"。
- grep 适合单纯的查找或匹配文本
- sed 适合编辑匹配到的文本
- awk 适合格式化文本,对文本进行较复杂格式处理
1. grep命令
grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...]
1.1 语法
grep [OPTION]... PATTERNS [FILE]
1.2 参数
参数 | 含义 |
---|---|
-a 或 --text | 不要忽略二进制的数据 |
-A<显示行数> 或 --after-context=<显示行数> | 除了显示符合范本样式的那一列之外,并显示该行之后的内容 |
-b 或 --byte-offset | 在显示符合样式的那一行之前,标示出该行第一个字符的编号 |
-B<显示行数> 或 --before-context=<显示行数> | 除了显示符合样式的那一行之外,并显示该行之前的内容 |
-c 或 --count | 计算符合样式的列数 |
-C<显示行数> 或 --context=<显示行数>或-<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前后的内容 | |
-d <动作> 或 --directories=<动作> | 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作 |
-e<范本样式> 或 --regexp=<范本样式> | 指定字符串做为查找文件内容的样式 |
-E 或 --extended-regexp | 将样式为延伸的正则表达式来使用 |
-f<规则文件> 或 --file=<规则文件> | 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式 |
-F 或 --fixed-regexp | 将样式视为固定字符串的列表 |
-G 或 --basic-regexp | 将样式视为普通的表示法来使用 |
-h 或 --no-filename | 在显示符合样式的那一行之前,不标示该行所属的文件名称 |
-H 或 --with-filename | 在显示符合样式的那一行之前,表示该行所属的文件名称 |
-i 或 --ignore-case : 忽略字符大小写的差别 | |
-l 或 --file-with-matches | 列出文件内容符合指定的样式的文件名称 |
-L 或 --files-without-match | 列出文件内容不符合指定的样式的文件名称 |
-n 或 --line-number | 在显示符合样式的那一行之前,标示出该行的列数编号 |
-o 或 --only-matching : 只显示匹配PATTERN 部分 | |
-q 或 --quiet或--silent : 不显示任何信息 | |
-r 或 --recursive | 递归搜索 |
-s 或 --no-messages | 不显示错误信息 |
-v 或 --revert-match | 显示不包含匹配文本的所有行 |
-V 或 --version | 显示版本信息 |
-w 或 --word-regexp | 只显示全字符合的列 |
-x --line-regexp | 只显示全列符合的列 |
-y | 此参数的效果和指定"-i"参数相同 |
grep root /etc/passwd # 在文件/etc/passwd中查找root
grep -i Root /etc/passwd # 忽略大小写
grep -o root /etc/passwd # 只显示匹配到的内容
grep -v root /etc/passwd # 输出所有不包含匹配内容的行
grep -c root /etc/passwd # 计算符合样式的数目
grep -r root /etc # 以递归的方式查找符合条件的文件
grep -l root /etc/passwd # 列出文件内容符合指定的样式的文件名称
2. sed命令
sed [-hnV][-e<script>][-f<script文件>][文本文件]
2.1 语法
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...
参数 | 含义 |
---|---|
-e | script 在处理输入时,将script中指定的命令添加到已有的命令中 |
-f | file 在处理输入时,将file中的指定的命令添加到已有的命令中 |
-n | 安静模式,或仅显示文本处理结果 |
# 下面的命令其实是sed -e 's/old/new/g' data.txt, -e参数被省略
sed 's/old/new/g' data.txt
# 如果需要执行多条命令,需要加上-e参数,命令间以:分隔,命令末尾及分号间不可以有空格
sed -e 's/old/new/g;s/black/white/g' data.txt
# 如果不想用分号,也可以用bash的次提示符进行命令分隔
sed -e '
> s/brown/green/
> s/fox/elephant/
> s/dog/cat/' data1.txt
# 读取脚本命令
sed -f script1.sed data.txt
# 显示所有
nl /etc/passwd | sed '5,7p'
# 仅显示5~7行
nl /etc/passwd | sed -n '5,7p'
- 动作说明
[n1,n2] function
function参数 | 含义 |
---|---|
a | 新增,a后面可以接字符串,这些字符串会在新一行出现(当前行的下一行) |
i | 插入,i后面可以接字符串,这些字符串会在新一行出现(当前行的上一行) |
c | 替换,c后面可以接字符串,这些字符串可以替换n1~n2之间的行 |
d | 删除,删除n1~n2之间的所有行 |
p | 打印 |
s | 替换,搭配正则表达式使用 |
nl /etc/passwd | sed '2a drink tea' # 在第2行前插入新行,内容为后接字符串
nl /etc/passwd | sed '2i drink tea' # 在第2行后插入新行,内容为后接字符串
nl /etc/passwd | sed '2,5d drink tea' # 删除2~5行
nl /etc/passwd | sed '2,5c drink tea' # 使用c后内容替换2~5行
2.2 替换标记
sed 's/old/new/' # 只替换每行中出现的第一处,将old替换为new,如果new为空,即为删除
sed 's/old/new/数字' # 表明新文本将替换第几处匹配的对象
sed 's/old/new/g' # 新文本将替换所有匹配的文本
sed 's/old/new/p' # 原先行的内容要打印出来
sed 's/old/new/w file' # 将替换的结果写入文件
sed命令并不会修改文件的数据,只会将修改后的数据发送到STDOUT
2.3 行寻址(line addressing)
默认情况下,在sed编辑器中使用的命令会作用于文本数据的所有行,如果想要对特定的行进行处理,需要使用行寻址(line addressing),sed编辑器中有两种行寻址
- 以数字表示行区间
sed '2s/dog/cat/' data1.txt # 替换第2行匹配到的第一个dog
sed '2,3s/dog/cat/' data1.txt # 替换第2~3行匹配到的第一个dog
sed '2,$s/dog/cat/' data1.txt # 替换从第2行开始的所有行匹配到的第一个dog,美元符$表示到文本尾部
- 以文本模式来过滤出行
sed '/character/s/dog/cat/' data1.txt # 仅将含character的行,其第1个匹配的dog替换为cat
2.4 命令组合
如果需要在单行执行多条命令,可以使用花括号将多条命令组合至一起
sed '2,$ {
> s/fox/elephant/
> s/dog/cat/
> }' data1.txt
3.awk
3.1 语法
awk [options] 'Pattern{Action}' file
options | 含义 |
---|---|
-f file | 从指定的文件中读取程序 |
-F fs | 指定fs作为划分文本的分隔符 |
-v var=value | 定义awk程序中的一个变量及其默认值 |
3.2 基础用法
- awk擅长文本格式化,并且将格式化以后的文本输出,所以awk最常用的动作就是print和printf
- awk可以灵活的将指定的字符与每列进行拼接,或者把指定的字符当做一个新列插入到原来的列中,也是awk格式化文本能力的体现
# 最简单的awk命令,仅执行了一个打印动作
awk '{print}' /etc/passwd
# 当awk处理文本会逐行进行处理,处理完当前行再处理下一行,awk默认以"换行符"为标记,识别每一行(连续空格默认为一个空格)
# -F参数指定分隔符
# $0 表示显示整行 ,$NF表示当前行分割后的最后一列($0和$NF均为内置变量),NF表示当前行被分隔符切开以后,一共有几个字段。
# $0指全部列,$1为第1列,$2第2列,$n第n列
awk -F: '{print $1}' /etc/passwd
# 如果需要显示多列,需要以逗号分隔,可用于组合文本的不同列
awk -F: '{print $1, $2, $NF}' /etc/passwd
# 除了输出文本中的列,我们还能够添加自己的字段,将自己的字段与文件中的列结合起来
awk -F: '{print $1, $2, "it is a test"}' /etc/passwd
3.3 awk特殊模式
3.3.1 BEGIN
BEGIN 模式指定了处理文本之前需要执行的操作:
3.3.2 END
END 模式指定了处理完所有行之后所需要执行的操作:
# 提取/etc/passwd前5行,并经过管道符 | 传递给awk
# 以冒号为分隔符,在处理文本前打印hello!,提取以冒号分隔的第1列,在文本处理结束后,打印The End
# 不同的大括号代表不同命令,需要使用分号进行分隔,并在外侧使用单引号进行界定,要注意的是,单引号区间内,不可以在使用单引号
head -5 /etc/passwd | awk -F: 'BEGIN {print "hello!"};{print $1};END {print "The End"}'
# 上述命令也可以通过使用shell的次提示符实现
head -5 /etc/passwd | awk -F: 'BEGIN {print "hello"}
> {print $1}
> END{print "The End"}
> '