两天高效学会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基础编程(赞赞赞)的主要内容,如果未能解决你的问题,请参考以下文章

两天高效学会Shell基础编程(赞赞赞)

赞赞赞❤️❤️N个神经网络可视化工具❤️❤️❤️

拒绝内卷,学会shell,走遍天下都不怕shell编程基础

精讲shell基础以及如何高效的学习shell编程

Shell脚本基础学习

2017-12-5Linux基础知识(15)shell编程