两天高效学会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
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小样x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值