shell刷题
目录
grep、awk、sed , 以及 cat、head、tail、less、more 命令
1. 统计文件行数
#解法1:awk
awk '{print NR}'| tail -n1
#awk print NR 打印每一行的行号
#tail -n1 只打印最后一行
#解法2:awk
awk 'END{print NR}'
#awk END{print NR} 最后打印行号
#关于 awk 脚本,我们需要注意两个关键词 BEGIN 和 END。
#BEGIN{ 这里面放的是执行前的语句}
#{这里面放的是处理每一行时要执行的语句}
#END {这里面放的是处理完所有的行后要执行的语句 }
#解法3:wc
wc -l
# wc -l 统计文件有多少行
# wc -wcl -w word多少单词 -c char 多少字符 -l line 多少行
#解法4:sed
sed -n '$='
# -n或--quiet或--silent 仅显示script处理后的结果。
# 正则表达式中 行尾定位符“$” 行首定位符“^”
#解法5:grep
grep -n "" |tail -n1| awk -F: '{print $1}'
# grep -n "" -n显示行号, 匹配"" 即显示每一行的行号
# awk -F: 只取第一列,即行号,以:分割
# tail -n1 只取最后一行,即总行数
#解法6:cat
cat -n |tail -1|awk '{print $1}'
# cat -n 显示每一行,并添加上行号
# tail -1 只取最后一行,即总行数
# awk -F 只取第一列,即行号,默认空格分隔
2. 打印文件最后5行
#解法1:
tail -5
#tail 从后往前看文件, -5 只看5行
# -f 循环读取,实时读取文件 -n 读多少行 只用-n n可以省略
3. 输出7的倍数
for i in {0..500..7}
do
echo $i
done
seq 0 7 500 # 或:seq [选项]... 首数 增量 尾数
4. 输出第5行内容
awk 'NR==5'
cat -n |grep 5|awk '{print $2}' #cat -n 显示每一行,并添加上行号
head -n 5 | tail -n 1 #先显示前5行,再从后往前显示一行
5. 打印空行的行号
awk '/^$/ {print NR}'
grep -n "^$" |awk -F : '{print $1}'
#删除空行
awk '!/^$/ {print $NF}'
sed '/^$/d'
6. 打印字母小于8
awk 'BEGIN{FS="";RS=" ";ORS="\n"}{if(NF<8)print$0}'
7. 统计所有进程占用内存大小的和
awk '{sum+=$6} END{print sum}'
8. 统计每个单词出现的个数
awk '{for(i=1;i<=NF;i++)a[$i]++} END{for (i in a){print i,a[i]}}'
cat $1 | tr -s ' ' '\n' |sort |uniq -c|sort | awk '{print $2" "$1}'
# cat 查看全部
#tr -s 将' '转化为 换行
#sort 排序
#uniq -c 统计行出现次数(需要先排序)
#sort 再排序,按升序显示
#awk 改变显示方式
9. 第二列是否有重复
awk '{print $2}' nowcoder.txt|sort|uniq -cd|sort -n
# awk 先筛选出第二列
# sort 排序
# uniq -cd -c统计每行行数 -d只显示重复行
# 再次排序按升序显示信息
10. 转置文件的内容
#解法1:
awk '{printf $1}' nowcoder.txt
awk '{printf $2}' nowcoder.txt
#先输出第一列,再输出第二列
#解法2:
awk '{
for(i=1;i<=NF;i++){rows[i]=rows[i]" "$i} # 这种数组的赋值学会使用
} END{
for(line in rows){print rows[line]}
}'
#第一个式子将每一列存到了一个行数组里
#第二个式子 END最终,输出行数组
11. 去掉所有包含 this 的句子
grep -v "this"
sed '/this/d'
12. 求平均值
#解法1:
awk 'BEGIN{sum=0}NR>1{sum+=$0}END{printf("%.3f",sum/(NR-1))}'
# 将第一行读为长度,将其他行作为数值求和
# 最后将和/长度,格式化小数点后三位输出
#解法2:(同1)
awk '{if(NR!=1)total+=$1} END{printf("%.3f\n",total/(NR-1))}'
# 除了第一行不读,将其他行作为数值求和
# 最后将 和/长度 (即:总行数-1),格式化小数点后三位输出
13. 去掉不需要的单词
#解法1: grep
grep -iv "b"
#grep -i ignore 忽略大小写 -v invert 不匹配
#即显示不含B和b的
#解法2: sed
sed '/B\|b/d'
#等同于
# sed '/b/d' | sed '/B/d'
# d delete 删除,将包含b或B的行,删除
#解法3: awk
awk '$0!~/[bB]/ {print $0}'
# $0表示整行
# 不包含b或B,输出整行
14. 打印每一行出现的数字个数
awk -F "" '{count=0;for(i=1;i<=NF;i++) {if($i>=1&&$i<=5) count++}sum+=count; print "line"NR" number:"count}END{print "sum is "sum}'
15. 判断输入的是否为 IP 地址
read -p "请输入IP地址:" IP
IP_CHECK=$(echo $IP|awk -F. '$1<255&&$2<255&&$3<255&&$4<255{print "R"}')
if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
if [ $IP_CHECK == "R" ]; then
echo "IP $IP 合法!"
else
echo "IP $IP 不合法!"
fi
else
echo "IP输错啦!"
fi
awk -F "." '{
if (NF == 4) {
for (i=1; i<5; i++) {
if ($i > 255 || $i < 0) {
print("no");break
}
}
if (i==5){print("yes")}
} else {
print("error")
}
}'
16. 将字段逆序输出文件的每行
awk -F ":" '{
for (i=1; i<=NF; i++) {
if (i==1) {
str = $1; continue
}
str = sprintf("%s:%s", $i, str)
}
print(str)
}'
awk -F: '{printf("%s:%s:%s:%s:%s:%s:%s\n",$7,$6,$5,$4,$3,$2,$1)}' nowcoder.txt
17. 域名进行计数排序处理
awk -F '/' '{print $3}'|sort|uniq -c|sort -r|awk '{print $1" "$2}'
awk -F '/' '{
countMap[$3]++;
}END{
for(domin in countMap){
print countMap[domin] " " domin
}
}' nowcoder.txt | sort -nr -k1 # r: 降序;n: 以数值来排序;k: 指定按照某一列进行排序
18.打印只有一个数字的行
awk -F '' '{
count=0
for(i=1;i<=NR;i++){
if($i>=0 && $i<=9){
count++
}
}
if(count==1){
print $0
}
}'
19. 格式化输出
awk -F "" '{
k=0
for (i=NF; i>0; i--) {
k++
str = sprintf("%s%s", $i, str)
if (k%3 == 0 && i>=2 && NF > 3) {
str = sprintf(",%s", str)
}
}
print(str)
str=""
}'
20. 处理文本
awk -F ":" '{
a[$1] = a[$1] $2 "\n" # 学会这种数组表示法,类似key-value
}
END {for (i in a){
printf("[%s]\n%s",i,a[i])
}
}' nowcoder.txt
21. nginx 日志分析 1-IP 统计
- 统计出 2020 年 4 月 23 号的访问 ip 次数,并且按照次数降序排序
awk '{
if(substr($4, 2, 11) == "23/Apr/2020") { # substr 中字符 从1开始计数
res[$1]++;
}
}END {
for(k in res) {
print res[k] " " k
}
}' | sort -nr -k 1 -t " "
22.统计某个时间段的 IP
- 2020 年 04 月 23 日 20-23 点的去重 IP 访问量
awk '{
if ($0 ~ /\[23\/Apr\/2020:2[0-2]/) { #使用正则表达式方式
a[$1]=1
}
} END {
print (length(a)) #length 函数使用
}'
23. 统计访问3次以上IP
awk '{
if ($1 in a) {
a[$1]++;
} else {
a[$1]=1
}
} END {
for (j in a) {
if (a[j] > 3) {
print a[j],j
}
}
}' nowcoder.txt | sort -r
24. 查询某个 IP 的详细访问情况
awk '{
if ($1 == "192.168.1.22") {
a[$7]++
}
} END {
for (i in a){
printf("%d %s\n",a[i], i)
}
}' | sort -r
25. 统计每分钟的请求数
awk -F ":" '{
res[$2 ":" $3]++;
}END{
for(k in res){
print res[k] " " k
}
}'|sort -nr -k1
26.查看各个状态的连接数
awk '{
if ($1 == "tcp") {
arr[$6]++
}
}END{
for(i in arr){
print i" "arr[i]
}
}' | sort -nr -k2
27. 查看和 3306 端口建立的连接
grep "3306" | grep -i "established" | awk '{print $5}' | awk -F ":" '{print $1}' | sort | uniq -c | awk '{print $1" "$2}' | sort -nr
grep "3306" | grep "ESTABLISHED" | awk '{
a[$5]++
}END{
for(i in a){
print a[i]" "i
}
}' | sort -nr -k1 | awk -F ":" '{
print $1
}'
28.输出每个 IP 的连接数
awk '/^tcp/{print $5}' | awk -F ":" '{
a[$1]++
}END{
for(i in a){
print i" "a[i]
}
}' | sort -nr -k2