概括:
grep:数据查找定位
awk:数据切片
sed:数据修改
类比SQL:
grep=select * from table
awk=select id from table
sed=update table set field=new where field = old
一,grep:用于文本搜索
- grep:global search regular expression (RE)and print out the line
- 基于正则表达式查找满足条件的行
- 语法:
- grep -i :忽略大小写
- grep -v:显示不被pattern匹配到的行
- grep -o:仅显示匹配到的字符串
- grep -E:使用扩展正则表达式
- grep -A -B -C:打印命中数据的上下文
- grep pattern -r dir/ 递归搜索
- grep -n :显示匹配的行号
- grep -c:统计匹配的行数
# grep:查找命令,重点
grep hello test.txt # 在test.txt文件里面查找hello
grep -i hello test.txt # 在test.txt文件里面查找hello,忽略大小写 i:ignore
cat test.txt | grep -i hello # 在test.txt文件里面查找hello,忽略大小写
cat test.txt | grep -o hello # 在test.txt文件里面查找hello,只展示匹配到的内容
cat test.txt | grep -o -m1 hello # 在test.txt文件里面查找第一个hello,-m后面表示匹配的个数 -m2表示展示2个,以此类推
grep -n root test.txt # 查找文件内容包含root的行数
grep -nv root test.txt # 查找文件内容不包含root的行数
grep ^s test.txt # 查找以s开头的行
grep n$ test.txt # 查找以n结尾的行
[kola@localhost ~]$ echo abcC | grep -i 'c'
abcC
[kola@localhost ~]$ echo abcC | grep -o 'c' # 只显示匹配到的内容
c
[kola@localhost ~]$ echo abcdef | grep -o 'c.' # .c:匹配c和后面的一个字符
cd
[kola@localhost ~]$ echo abcdde | grep -o 'c.*'
cdde
对这种需要搜索多个关键词的,可以新建一个keyword后缀的文件,然后编辑,输入关键字,然后结合grep命令进行操作
- 练习:找出首页是否有死链
curl -s https://www.testing-studio.com/
| grep href
| grep -o "http[^\"']*"
| while read line;
do curl -s -I $line
| grep 200
&& echo 200 $line
|| echo ERR $line;
done
二,awk:文本切割
-
名字来源于三个作者名字的简称
-
根据定位到的数据行处理其中的分段
-
把文件进行逐行读入,如果不指定分隔符,默认以空格为分隔符把它分隔开,再把替换的部分进行处理
-
语法:awk ‘pattern{action}’
-
pattern:正则表达式
-
action:对匹配到的内容执行的命令
常用参数: -
FILENAME :awk浏览的文件名
-
BEGIN:处理文本前要执行的动作
-
END:处理文本后要执行的动作
-
FS:设置输入域分隔符,等价于命令行-F选项
-
NF:浏览记录的域的个数(列数)
-
NR:已读的记录数(行数)
-
OFS:输出域分隔符
-
ORS:输出记录分隔符
-
RS:控制记录分隔符
-
$0:整条记录
-
$1:表示当前行的第一个域…以此类推
-
常用操作:
-
awk ‘BEGIN{}END{}’ 开始和结束
-
awk ‘/Running/’ 正则匹配
-
awk ‘/aa/,/bb/’ 区间选择
-
awk ‘$2~/xxx/’ 字段匹配
-
awk ‘NR==2’ 取第二行
-
awk ‘NR>1’ 去掉第一行
-
awk的字段处理
-
-F 参数指定字段分隔符
-
BEGIN{FS=“_”}也可以表示分隔符
-
$0 表示原来的行
-
$1 代表第一个字段(默认用空格来进行分割)
-
$N 代表第N个字段
-
$NF表示最后一个字段
# awk '$2~/xxx/'使用
# TEST.txt内容:
# baidu 200
# sina 300
# tencent 200
# 操作:查找状态码为200的数据
$ cat TEST.txt | awk '$2~/200/'
baidu 200
tencent 200
# 操作:查找状态码非200的数据
$ cat TEST.txt | awk '$2!~/200/'
sina 300
这个时候awk -F 后面的 | 表示或
匹配用户名
打印出用户名
如果要打印多个匹配内容,可以用逗号进行分割,但是结果不会显示逗号
grep和awk一起用
三,sed:文本替换
-
流编辑处理器
-
根据定位到的数据行修改数据
-
语法:sed [address] X [options]
-
-e<script> 以选项中指定的script来处理输入的文本文件
-
-f<script> 以选项中指定的script来处理输入的文本文件
-
-i 直接修改原文件内容
-
常用动作:
a:新增 sed -e ‘4 a newline’ 在第四行里新增一行(指定行后面新增)
c:取代 sed -e ‘2,5c No 2-5 number’ 用c后面的内容去取代2-5行的内容
d:删除 sed -e ‘2,5d’ 删除2-5行的内容
i: 插入 sed -e ‘2i newline’ 第二行前面插入新行(指定行前面新增)
p:打印 sed -n ‘/root/p’ 匹配到正则后再进行打印
s:取代 sed -e ‘s/old/new/g’ 用new替代old(加g是修改全部符合条件的,不加只修改第一个匹配的) -
替换单个
$ echo "cat dog cat" | sed "s/cat/fish/"
fish dog cat # 输出结果
- 替换多个
$ echo "cat dog cat" | sed 's/cat/fish/g'
fish dog fish # 输出结果
- 我们除了可以用/号来替换,还可以用其他符号进行替换,输出结果都是一样的。只是常规都是用/号
$ echo "cat dog cat" | sed 's\cat\fish\g'
fish dog fish
$ echo "cat dog cat" | sed 's#cat#fish#g'
fish dog fish
- sed还支持替换文件内容
# 原文件内容
$ cat test.txt
hello kola
kola
hhhhhhh
Hello kola
# 替换原文件内容:这个替换只是把需要替换的文件读到模式空间,改的是空间里面的内容,
# 和原始文件无关
$ sed "s/kola/lucy/" test.txt
hello lucy
lucy
hhhhhhh
Hello lucy
# 如果需要替换原始文件的内容,需要加上 “-i”参数
sed -i "s/kola/lucy/" test.txt
- 如果担心自己因为手滑删除文件,我们可以进行备份
sed -i "s/kola/lucy/" test.txt.bak
- 结合BEGIN,END使用
语法:‘BEGIN{ }END{ }’
# 求出3行数字里中间数的和
$ echo -e "1|2|3\n4|5|6|\n7|8|9"
| awk -F '|'
'BEGIN {a=0} {a=a+$2}END{print a}'
输出:2 5 8
# 求2行数字中间的值,并求中间值的和
$ echo -e '1|2|3\n4|5|6'
| awk -F '|'
'BEGIN{a=0}{a=a+$2;print $2}END{print a}'
输出:2 5 7
练习题:
1,取出某论坛帖子的点赞人数
```bash
$ a=`curl -s https://testerhome.com/topics | grep -o 'href="/topics/[0-9]*"' | awk -F '/|"' '{print $4}'`; for id in $a;do url='https://testerhome.com/topics/'$id; zan=`curl -s $url | grep -o -m1 '<span>[0-9]*' | awk -F '>' '{print $2}'`;if [ -n "$zan" ];then echo $url '点赞人数 '$zan;else echo $url '点赞人数' 0;fi;done| awk -F '/' '{print $NF}'
- 2 ,进行加减乘除操作,这里注意,写除法的时候不能按照原来那么写,需要借助awk或者三方工具进行处理
read -p "please enter:" a
read -p "please enter:" b
echo "$(($a+$b))"
echo "$(($a-$b))"
echo "$(($a*$b))"
echo `awk "BEGIN{print \"$a\"/\"$b\"}"`