三剑客
grep 行匹配
使用正则表达式搜索文本,并把匹配的行内容打印出来
-
语法:grep [pattern] xxx
-
patton:
- -i 忽略大小写
- -l 输出包含匹配项的文件名
- -n 显示行号
- -v 不显示匹配的行
- -o 把每个匹配的内容用独立的行显示
- -E 使用拓展正则表达式
- -A -B -C 打印命中数据的上下文
- -r [dir] 递归搜索 遍历dir目录所有文件
-
正则表达式
基本表达式(BRK)
^ 开头 $ 结尾
[a-z][0-9] 区间 如果区间开头带有^,表示不能匹配区间内的元素
* 0个或多个
. 表示任意字符
基本正则(BRK)与扩展正则的区别(ERE) -E
? 非贪婪匹配 匹配尽量少的元素
+ 一个或多个
() 分组
{} 范围约束
| 匹配多个表达式的任何一个
grep 'text' *.txt # 匹配所有txt后缀文件包含text的行
grep -n '[a-z]\{5\}' a.txt # 匹配a.txt文件所有 包含5个连续小写字母的行,显示行号
grep -l 'testerhome' -r /root # 匹配/root目录下(包含子目录),所有包含‘testerhome’字符串的文件
grep -l 'testerhome' -d skip /root # 同上(不包含子目录)
awk 数据提取
- 语法:awk [pattern] xxx
- pattern
- -F 给字段指定分隔符 (这个分隔符是字段本身的元素)
- OFS 给字段添加分隔符 (这个分隔符是自己输入的)
- NF 字段数 指定最后一个元素 NF-1 即指定倒数第二个元素
- NR 记录数(行数), NR>1 即指定第一行之后的内容
- RS 给单行内容指定分隔符 分割为行 (这个分隔符是字段本身的元素)
- ORS 给多行内容添加分隔符 分割、 (这个分隔符是自己输入添加的)
echo '1 2 3' | awk '{print $0}' # 打印所有内容 输出 1 2 3
echo '123' | awk -F '2' '{print $2}' # 以2为分隔符,打印第二个元素,输出 3
echo '1 2 3' | awk '{print $2}' # 默认以空格/tab为分隔符,打印第二个元素,输出 2
echo '1#2#3' | awk -F '#' '{OFS="-"}{print $1,$2,$3}' # 将 % 替换成 - 输出
awk 'NR>100' a.txt # 打印第100行之后的内容
echo '1 2 3' | awk '{print $NF-1}' # 打印倒数第2个元素
echo $PATH | awk 'BEGIN{RS=":"}{print NR,$0}' # 以 : 分割,单行拆分为多行
sed 数据操作
- 语法:sed [pattern] [content] xxx
- pattern:
- -i 直接修改源文件
- -n 打印第几行
- -e 接多个content
echo '1
2
3' | sed -n 1,2p # 输出第1,2行内容
echo '1
2
2' | sed 's/2/xxxx/' #将第一个2替换为xxxx
echo '1
2
2' | sed -e 's/1/xxx/' -e 's/2/ccc/' # 将1,2分别替换为xxx、ccc(替换第一个2)
echo '12341234' | sed 's/2/x/g' # 将所有的2都替换为x
演练
curl 'https://testerhome.com/' > a.txt
grep '^ *<a title=".*" href="/.*">[^>]*</a>' a.txt # 匹配所有帖子
grep '^ *<a title=".*" href="/.*">[^>]*</a>' a.txt | wc -l # 输出帖子数量
grep -n '^ *<a title=".*" href="/.*">[^>]*</a>' a.txt | awk -F 'title' '{print $2}' # 以title为分割符,输出第2个内容
grep -n '^ *<a title=".*" href="/.*">[^>]*</a>' a.txt | awk -F\" '{print $2,$8}' # 输出所有title,href
grep -n '^ *<a title=".*" href="/.*">[^>]*</a>' a.txt | awk -F\" '{print $2,$8}' | sed 's/articles/topics/g' # 将articles替换为topics

浙公网安备 33010602011771号