两天高效学会Shell基础编程(赞赞赞)
Posted 小样5411
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两天高效学会Shell基础编程(赞赞赞)相关的知识,希望对你有一定的参考价值。
目录
前言
所有的题尽量不用,tail、cat、grep、awk这种命令直接执行得出结果,全用bash shell语句编程,这样程序最高效
以下是我学Shell的方法,供参考
1、先花半天时间看下基本用法:Shell教程-菜鸟教程
注:如果你觉得直接看无聊,可以先花半天时间刷牛客前五题简单题,看看排行前几名写法,稍微就入门了一丢丢,然后再看菜鸟教程
2、再把牛客Shell题目花一天时间刷完,不会的看看排行里别人写的,尽量自己按思路,自己完成,一定自己思考,自己敲,别复制别人的运行,可以看别人思路,自己写,但别看一下写一下,大概总共花2天时间,shell编程基础点开发就没问题,多动手学得快,更深刻
自己思考完成20题,shell语法、基本编程就没啥问题,反正我是这么感觉的,集中时间刷完
题目
20道
1、统计文件行数
题目
描述
写一个 bash脚本以输出一个文本文件 nowcoder.txt中的行数
...
代码
while read val # 逐行读取,val即为每行
do
# 每读一行就+1,即自增
((line++))
done < ./nowcoder.txt # 每次完成就重定向到文件,继续读取,<表示重定向
echo $line
2、打印文件的最后5行
后面都直接上代码
#!/bin/bash
line=0
while read val
do
line=$((line+1))
done < nowcoder.txt
line=$((line-5))
cnt=0
while read val
do
if (($cnt >= $line )) # 相当于line前面的不输入,输入其后面的
then
echo $val
fi
cnt=$((cnt+1))
done < nowcoder.txt
3、输出7的倍数
for i in 0..500
do
if (( i % 7 == 0))
then
echo $i
fi
done
4、输出第5行的内容
#!bin/bash
num=1
while read line
do
if ((num == 5))
then
echo $line
fi
((num++))
done < nowcoder.txt
5、打印空行的行号
#!/bin/bash
num=1
while read line
do
if [ -z $line ]
then
echo $num
fi
((num++))
done < nowcoder.txt
6、去掉空行
#!/bin/bash
while read line
do
if [ -z $line ]
then
continue
else
echo $line
fi
done < nowcoder.txt
7、打印字母数小于8的单词
# 思路1:先分割存入数组,然后分别统计
# 思路2:遍历字符串,num=0,遇到空格就判断,看是否可以输出
#!/bin/bash
read line < nowcoder.txt # 读nowcoder.txt一行
for n in $line
do
if [ "$#n" -lt 8 ]
then
echo $n
fi
done
8、统计所有进程占用内存大小的和
# 读取每行,然后获取第二列值,将其相加
sum=0
while read line
do
arr=($line)
((sum+=arr[5]))
done < nowcoder.txt
echo $sum
9、 统计每个单词出现的个数
典型题,去重、统计个数都一样的
# 解题步骤:
# 1、逐行读取,每一行的单词存到map中,相当于一个初始化过程
# 2、用一个数组存去重后的单词出现次数
# 3、冒泡排序
# 4、将排序后的次数与map中的value对比,相等就依次输出,这样就是排序后的
declare -A map
while read line
do
arr=$line
for i in $arr[@]
do
if [ -z $map[$i] ]
then
map[$i]=1
else
((map[$i]++))
fi
done
done < nowcoder.txt
mm=()
for value in $map[@]
do
mm[$#mm[@]]=$value
done
len=$#mm[@]
for ((i=0;i<len;i++))
do
for ((j=i+1;j<len;j++))
do
if [ $mm[$i] -gt $mm[$j] ]
then
tmp=$mm[$i]
mm[$i]=$mm[$j]
mm[$j]=$tmp
fi
done
done
for ((k=0;k<len;k++))
do
for key in $!map[@]
do
if [ $map[$key] -eq $mm[$k] ]
then
echo $key $map[$key]
fi
done
done
10、第二列是否有重复
# 解题步骤
# 1、构造map,key-value为第2列元素-出现次数
# 2、将map中的元素出现次数放到数组中
# 3、对数组排序
# 4、按照排序顺序输出
declare -A map
# 第一步:构造map
while read -a line
do
key=$line[1]
if [ -z $map[$key] ]
then
map[$key]=1
else
((map[$key]++))
# echo $key $map[$key]
fi
done < nowcoder.txt
# 第二步:将重复的元素次数放到数组中
arr=()
for key in $!map[@]
do
if [ $map[$key] -gt 1 ]
then
echo $map[$key] $key
arr[$#arr[@]]=$map[$key]
fi
done
# 第三步:对arr数组(出现次数)排序
len=$#arr@
for (( i=0;i<len;i++ ))
do
for (( j=$[$i+1];j<len;j++ ))
do
if [ $arr[$i] -gt $arr[$j] ]
then
# 交换
tmp=$arr[$i]
arr[$i]=$arr[$j]
arr[$j]=$tmp
fi
done
done
#第四步:输出
for (( k=0;k<len;k++ ))
do
for key in $!map[@]
do
if [ $map[$key] -eq $arr[$k] ]
then
echo $map[$key] $key
fi
done
done
11、转置文件的内容
# 读取每行,得出行数与列数,然后遍历,注意shell是没有二维数组的,只有一维
# 第一步:读取每行,放到数组中
arr=()
while read line
do
arr[$#arr[@]]=$line
done < nowcoder.txt
# 第二步:转置输出,即行列调换遍历输出
rows=$#arr[@]
m=($arr[0])
columns=$#m[@]
for (( i=0;i<$columns;i++ ))
do
for (( j=0;j<$rows;j++ ))
do
tmp=($arr[$j])
echo "$tmp[$i] "
done
done
12、打印每一行出现的数字个数
# 字符串截取、正则表达式
line_num=0 # 行号
sum=0 # 数字总数
while read line
do
count=0 # 记录每行的数字个数
((line_num++))
for (( i=0;i<$#line;i++ ))
do
if [[ $line:$i:1 =~ [1-5] ]]
then
((count++))
fi
done
((sum+=count))
echo "line$line_num number:$count"
done < nowcoder.txt
echo "sum is $sum"
13、 去掉所有包含this的句子
# 读取每行,每行生成数组,看是否含this,有则continue,否则输出
while read line
do
flag=0
for i in $line
do
if [ $i == "this" ] # 注意==和-eq的区别,==比较字符串,-eq比较对应的值
then
flag=1
break
fi
done
if [ $flag -eq 0 ]
then
echo $line
fi
done < nowcoder.txt
14、求平均值
read len # 输入长度
loop_time=$len
sum=0
while (($loop_time > 0))
do
read ele
((sum+=ele))
((loop_time--))
done
echo "scale=3;$sum/$len" | bc # bc工具显示小数
15、去掉不需要的单词
# 读取输入
while read line
do
len=$#line
flag=1
# 判断字符串的每个字符
for (( i=0;i<len;i++ ))
do
if [[ $line:$i:1 == "B" || $line:$i:1 == "b" ]]
then
flag=0
break
fi
done
if [ $flag -eq 1 ]
then
echo $line
fi
done
16、判断输入的是否为IP地址
# 有四位数字组成,且数字范围均在0~255之间
# Shell怎么做分隔?按.分隔,返回到数组,$parameter//pattern/string
while read line
do
arr=($line//./ )
len=$#arr[@]
if [[ $len != 4 ]]
then
echo "error"
continue
fi
flag=1
for ele in $arr[@]
do
if [ $ele -ge 0 -a $ele -le 255 ]
then
continue
else
flag=0
break
fi
done
if [ $flag -eq 1 ]
then
echo "yes"
else
echo "no"
fi
done < nowcoder.txt
17、将字段逆序输出文件的每行
这里用awk会更快,更容易懂,我自己用shell语句写,不好写感觉
# NF表示一行有多少个单词,-F ":"表示按:分隔
awk -F ":" ' for(i=NF;i>=1;i--)
if (i != 1)
printf $i ":"
else
print $i
' nowcoder.txt
18、域名进行计数排序处理
# 这个就类似字符串重复次数,并排序
declare -A map
while read line
do
tmp=($line//\\// ) # 反斜杠转义
name=$map[$tmp[1]]
# echo $name
if [ -z $name ]
then
map[$tmp[1]]=1
else
((map[$tmp[1]]++))
fi
done < nowcoder.txt
# 构造数组
arr=()
for key in $!map[@]
do
arr[$#arr[@]]=$map[$key]
done
len=$#arr[@]
# 对数组排序(降序), 用了冒泡
for (( i=0;i<len;i++ ))
do
for (( j=i+1;j<len;j++ ))
do
if [ $arr[$i] -lt $arr[$j] ]
then
tmp=$arr[$i]
arr[$i]=$arr[$j]
arr[$j]=$tmp
fi
done
done
# 按数组排序顺序输出
for (( k=0;k<len;k++ ))
do
for key in $!map[@]
do
if [ $map[$key] -eq $arr[$k] ]
then
echo $map[$key] $key
fi
done
done
19、打印等腰三角形
记得是最开始学C语言,课本习题就是这个
for (( i=1;i<=5;i++ ))
do
# 打印空格
for (( j=5-i;j>=1;j-- ))
do
printf " "
done
# 打印星星
for (( k=1;k<=i;k++ ))
do
printf "* "
done
printf "\\n"
done
20、打印只有一个数字的行
while read line
do
count=0
for (( i=0;i<$#line;i++ ))
do
if [[ $line:$i:1 =~ [0-9] ]]
then
((count++))
fi
done
if [ $count -eq 1 ]
then
echo $line
fi
done < nowcoder.txt
以上是关于两天高效学会Shell基础编程(赞赞赞)的主要内容,如果未能解决你的问题,请参考以下文章