所有的题尽量不用,tail、cat、grep、awk这种命令直接执行得出结果,全用bash shell语句编程,这样程序最高效
以下是我学Shell的方法,供参考
1、先花半天时间看下基本用法:Shell教程-菜鸟教程
注:如果你觉得直接看无聊,可以先花半天时间刷牛客前五题简单题,看看排行前几名写法,稍微就入门了一丢丢,然后再看菜鸟教程
2、再把牛客Shell题目花一天时间刷完,不会的看看排行里别人写的,尽量自己按思路,自己完成,一定自己思考,自己敲,别复制别人的运行,可以看别人思路,自己写,但别看一下写一下,大概总共花2天时间,shell编程基础点开发就没问题,多动手学得快,更深刻
自己思考完成20题,shell语法、基本编程就没啥问题,反正我是这么感觉的,集中时间刷完
20道
题目
描述
写一个 bash脚本以输出一个文本文件 中的行数
...
代码
while read val # 逐行读取,val即为每行
do
# 每读一行就+1,即自增((line++))
done < ./ # 每次完成就重定向到文件,继续读取,<表示重定向
echo $line
后面都直接上代码
#!/bin/bash
line=0
while read val
doline=$((line+1))
done < line=$((line-5))
cnt=0
while read val
doif (($cnt >= $line )) # 相当于line前面的不输入,输入其后面的thenecho $valficnt=$((cnt+1))
done <
for i in {0..500}
doif (( i % 7 == 0))thenecho $ifi
done
#!bin/bash
num=1
while read line
doif ((num == 5))thenecho $linefi((num++))
done <
#!/bin/bash
num=1
while read line
doif [ -z $line ]thenecho $numfi((num++))
done <
#!/bin/bash
while read line
doif [ -z $line ]thencontinueelseecho $linefi
done <
# 思路1:先分割存入数组,然后分别统计
# 思路2:遍历字符串,num=0,遇到空格就判断,看是否可以输出
#!/bin/bash
read line < # 读一行
for n in $line
doif [ "${#n}" -lt 8 ]thenecho ${n}fi
done
# 读取每行,然后获取第二列值,将其相加
sum=0
while read line
doarr=($line)((sum+=arr[5]))
done <
echo $sum
典型题,去重、统计个数都一样的
# 解题步骤:
# 1、逐行读取,每一行的单词存到map中,相当于一个初始化过程
# 2、用一个数组存去重后的单词出现次数
# 3、冒泡排序
# 4、将排序后的次数与map中的value对比,相等就依次输出,这样就是排序后的declare -A mapwhile read line
doarr=$linefor i in ${arr[@]}doif [ -z ${map[$i]} ]thenmap[$i]=1else((map[$i]++))fidonedone < =()for value in ${map[@]}
domm[${#mm[@]}]=${value}
donelen=${#mm[@]}
for ((i=0;i<len;i++))
dofor ((j=i+1;j<len;j++))doif [ ${mm[$i]} -gt ${mm[$j]} ]thentmp=${mm[$i]}mm[$i]=${mm[$j]}mm[$j]=$tmpfidonedonefor ((k=0;k<len;k++))
dofor key in ${!map[@]}doif [ ${map[$key]} -eq ${mm[$k]} ]thenecho $key ${map[$key]}fidone
done
# 解题步骤
# 1、构造map,key-value为第2列元素-出现次数
# 2、将map中的元素出现次数放到数组中
# 3、对数组排序
# 4、按照排序顺序输出
declare -A map
# 第一步:构造map
while read -a line
dokey=${line[1]}if [ -z ${map[${key}]} ]thenmap[${key}]=1else((map[${key}]++))# echo $key ${map[${key}]}fi
done <
# 第二步:将重复的元素次数放到数组中
arr=()
for key in ${!map[@]}
doif [ ${map[$key]} -gt 1 ]thenecho ${map[$key]} $keyarr[${#arr[@]}]=${map[$key]}fi
done
# 第三步:对arr数组(出现次数)排序
len=${#arr{@}}
for (( i=0;i<len;i++ ))
dofor (( j=$[$i+1];j<len;j++ ))doif [ ${arr[$i]} -gt ${arr[$j]} ]then# 交换tmp=${arr[$i]}arr[$i]=${arr[$j]}arr[$j]=$tmpfidone
done
#第四步:输出
for (( k=0;k<len;k++ ))
dofor key in ${!map[@]}doif [ ${map[${key}]} -eq ${arr[$k]} ]thenecho ${map[$key]} ${key}fidone
done
# 读取每行,得出行数与列数,然后遍历,注意shell是没有二维数组的,只有一维
# 第一步:读取每行,放到数组中
arr=()
while read line
doarr[${#arr[@]}]=$line
done <
# 第二步:转置输出,即行列调换遍历输出
rows=${#arr[@]}
m=(${arr[0]})
columns=${#m[@]}
for (( i=0;i<$columns;i++ ))
dofor (( j=0;j<$rows;j++ ))dotmp=(${arr[$j]})echo "${tmp[$i]} "done
done
# 字符串截取、正则表达式
line_num=0 # 行号
sum=0 # 数字总数
while read line
docount=0 # 记录每行的数字个数((line_num++))for (( i=0;i<${#line};i++ ))doif [[ ${line:$i:1} =~ [1-5] ]]then((count++))fidone((sum+=count))echo "line${line_num} number:${count}"
done <
echo "sum is ${sum}"
# 读取每行,每行生成数组,看是否含this,有则continue,否则输出
while read line
doflag=0for i in $linedoif [ $i == "this" ] # 注意==和-eq的区别,==比较字符串,-eq比较对应的值thenflag=1breakfidoneif [ $flag -eq 0 ]thenecho $linefi
done <
read len # 输入长度
loop_time=$len
sum=0
while (($loop_time > 0))
doread ele((sum+=ele))((loop_time--))
done
echo "scale=3;$sum/$len" | bc # bc工具显示小数
# 读取输入
while read line
dolen=${#line}flag=1# 判断字符串的每个字符for (( i=0;i<len;i++ ))doif [[ ${line:$i:1} == "B" || ${line:$i:1} == "b" ]]thenflag=0breakfidoneif [ $flag -eq 1 ]thenecho $linefi
done
# 有四位数字组成,且数字范围均在0~255之间
# Shell怎么做分隔?按.分隔,返回到数组,${parameter//pattern/string}
while read line
doarr=(${line//./ })len=${#arr[@]}if [[ $len != 4 ]]thenecho "error"continuefiflag=1for ele in ${arr[@]}doif [ $ele -ge 0 -a $ele -le 255 ]thencontinueelseflag=0breakfidoneif [ $flag -eq 1 ]thenecho "yes"elseecho "no"fi
done <
这里用awk会更快,更容易懂,我自己用shell语句写,不好写感觉
# NF表示一行有多少个单词,-F ":"表示按:分隔
awk -F ":" '{ for(i=NF;i>=1;i--)if (i != 1){{printf $i ":"}} else {{print $i}}}'
# 这个就类似字符串重复次数,并排序
declare -A map
while read line
dotmp=(${line//// }) # 反斜杠转义name=${map[${tmp[1]}]}# echo $nameif [ -z $name ]thenmap[${tmp[1]}]=1else((map[${tmp[1]}]++))fi
done <
# 构造数组
arr=()
for key in ${!map[@]}
doarr[${#arr[@]}]=${map[$key]}
done
len=${#arr[@]}
# 对数组排序(降序), 用了冒泡
for (( i=0;i<len;i++ ))
dofor (( j=i+1;j<len;j++ ))doif [ ${arr[$i]} -lt ${arr[$j]} ]thentmp=${arr[$i]}arr[$i]=${arr[$j]}arr[$j]=$tmpfidone
done
# 按数组排序顺序输出
for (( k=0;k<len;k++ ))
dofor key in ${!map[@]}doif [ ${map[${key}]} -eq ${arr[$k]} ]thenecho ${map[$key]} ${key}fidone
done
记得是最开始学C语言,课本习题就是这个
for (( i=1;i<=5;i++ ))
do# 打印空格for (( j=5-i;j>=1;j-- ))doprintf " "done# 打印星星for (( k=1;k<=i;k++ ))doprintf "* "doneprintf "n"
done
while read line
docount=0for (( i=0;i<${#line};i++ ))doif [[ ${line:$i:1} =~ [0-9] ]]then((count++))fidoneif [ $count -eq 1 ]thenecho $linefi
done <
本文发布于:2024-02-04 22:41:18,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170718011760353.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |