bash shell笔记——循环结构

0 引言

本文主要介绍linux bash shell循环结构的基本使用

1 测试环境

查看系统版本:

uname -a : Ubuntu 18.04

查看bash版本:

bash -version : GNU bash, version 4.4.20(1)-release

创建.sh文件:

vim 00test.sh

修改00test.sh权限:

chmod 777 00test.sh 或 chmod +x 00test.sh

修改文件内容并保存:

bash 复制代码
#!/bin/bash
echo "Hello World!"

执行.sh文件:

./00test.sh

完成上述操作后会在终端中打印"Hello World!",到此,一个简单的shell脚本就完成了,本文后续内容将不再重复上述步骤

2 for循环
bash 复制代码
#!/bin/bash 
# 用 /bin/bash 这个可执行文件来解释并运行这个脚本

# shell使用"#"进行单行注释

# ----------------------------------------------------------
# 1 C 语言风格的 for 命令(单个变量)
for (( i=0; i<10; i++ ))
do
    # 使用"echo"命令来打印文本,类似于C中的"printf"
    # 若打印的是变量,需要在变量名前加"$",类似于C语言的"%d"
    echo "num : $i"
done

# ----------------------------------------------------------
# 2 C 语言风格的 for 命令(多个变量)
for (( i=0, j=9; i<10; i++, j-- ))
do
    echo "num_i : $i  num_j : $j"
done

# ----------------------------------------------------------
# 3 读取列表中的值
for num in 1 2 3 4 5
do
    echo "num : $num"
done

# ----------------------------------------------------------
# 4 读取列表中的复杂值
# 优雅的遍历 I'm from Xi'an and used to be in New York
# for循环假定每个值都是用空格分割的,
# 对于包含空格的数据值可用双引号括起来
# 如果要使用单引号,需要在单引号前加"\"或使用双引号括起来
for word in I\'m from "Xi'an" and used to be in "New York" 
do
    echo "word : $word"
done

# ----------------------------------------------------------
# 5 从变量读取列表
# 定义变量list
list="1 2 3 4 5" 
# 向list中添加值,方法1:
list="$list 6 7 8"
# 向list中添加值,方法2:
list=$list" 9 10"
# 引用变量时需在变量名前加"$"
for num in $list
do
    echo "num : $num"
done

# ----------------------------------------------------------
# 6.1 从命令读取值(cat)
# 在本脚本同级目录下创建01test.txt,并写入以下内容:
# apple banana orange
# dog cat 
# book
# 同级目录下直接将文件名赋值给变量filename
# 否则需要使用绝对路径
filename=01test.txt
# cat命令用于读取文件01test.txt内容,并返回一个字串列表
for word in `cat $filename`
do
    echo "word : $word"
done

# ----------------------------------------------------------
# 6.2 从命令读取值(ls)
# ls命令用于列出当前目录下的文件和文件夹
# 除了 ls 、cat 命令外,还可以使用 find 和 grep 等命令
for file in `ls`
do
    echo "word : $file"
done

# ----------------------------------------------------------
# 7.1 更改字段分隔符
# 测试6.1时会发现打印内容为6行,而不是3行,
# 其原因为默认情况下 bash shell 会将空格、制表符、换行符作为分隔符
# 分隔符是特殊的环境变量 IFS (内部字段分隔符,internal field separator)
# 若想分类打印6.1的内容,需要更改字段分隔符:将IFS的值更改为换行符
filename=01test.txt
# 更改字段分隔符为换行符
IFS=$'\n'
for word in `cat $filename`
do
    echo "word : $word"
done

# ----------------------------------------------------------
# 7.2 更改字段分隔符并还原
# 示例7.1中,修改IFS值后,该脚本的其他地方将沿用该值,该操作存在问题
# 例如在同一脚本中可能处理多个文件,这些文件的分隔符可能不同
# 为避免上述问题发生,可在修改前先保存原IFS值,用完后再改回来
# 保存原IFS值
IFS_OLD=$IFS
filename=01test.txt
# 更改字段分隔符为换行符
IFS=$'\n'
for word in `cat $filename`
do
    echo "word : $word"
done
# 改回原IFS值
IFS=$IFS_OLD

# 可指定多个IFS字符,示例如下
IFS=$'\n':;*
# 该赋值会将换行符、冒号、分号和星号作为字段分隔符
3 while循环
bash 复制代码
#!/bin/bash

# ----------------------------------------------------------
# 1 while 的基本格式
num=5
# -gt : great than 大于
while [ $num -gt 0 ] 
do
    echo "num : $num"
    num=$[$num-1]         # 法1:使用"$[]"进行数学运算
    # num=`expr $num - 1` # 法2:使用"expr"命令进行数学运算
done

# ----------------------------------------------------------
# 2 使用多个测试命令
# while语句行可定义多个测试命令
# 每个测试命令都出现在单独的一行上
# 只有最后一个测试命令的退出状态码会被用来决定什么时候结束循环
num=5
# -ge : great equal 大于等于
while echo $num 
    [ $num -ge 0 ] 
do 
    echo "num : $num" 
    num=$[ $num - 1 ] 
done
4 until循环
bash 复制代码
#!/bin/bash

# ----------------------------------------------------------
# 1 使用多个测试命令
# until语句行可定义多个测试命令
# 每个测试命令都出现在单独的一行上
# 只有测试命令的退出状态码不为0才会执行循环中列出的命令
# 下述示例中,当num=5时,
# [ $num -eq 0 ]不成立,退出状态码不为0,执行循环中的命令
# 当num=0时,[ $num -eq 0 ]成立,退出状态码为0,退出循环
num=5
until echo $num 
    [ $num -eq 0 ] 
do 
    echo "num : $num" 
    num=$[ $num - 1 ]
done
5 嵌套循环
bash 复制代码
#!/bin/bash

# ----------------------------------------------------------
# 1 示例1
for (( a = 1; a <= 3; a++ )) 
do 
    echo "a : $a ----" 

    for (( b = 1; b <= 3; b++ )) 
    do 
        echo "b : $b" 
    done 
done

# ----------------------------------------------------------
# 2 示例2
num1=3
while [ $num1 -ge 0 ] 
do 
    echo "num1 : $num1 ---" 

    for (( num2 = 1; $num2 <= 3; num2++ )) 
    do
        echo "num2 : $num2" 
    done 
    
    num1=$[ $num1 - 1 ] 
done
6 循环控制
bash 复制代码
#!/bin/bash

# ----------------------------------------------------------
# 1 break 命令跳出单层循环
for i in 1 2 3 4 5
do
    echo "i : $i"

    if [ $i -eq 3 ]
    then
        break
    fi
done

# ----------------------------------------------------------
# 2 break n 命令跳出多层循环
# 若不指定n,则默认跳出1层循环
for (( i = 1; i <= 5; i++ )) # 第 3 层循环
do
    echo "i : $i ---"

    for (( j = 1; $j <= 5; j++ )) # 第 2 层循环
    do
        echo "j : $j --"

        for ((k = 1; $k <= 5; k++)) # 第 1 层循环
        do
            echo "k : $k"

            if [ $k -eq 2 ]
            then
                break 2 # 跳出第 2 层循环
            fi
        done
    done
done

# ----------------------------------------------------------
# 3 continue 命令结束当前循环
for i in 1 2 3 4 5
do
    if [ $i -eq 3 ] # 若i=3,则结束当前循环(不再打印 i : 3)
    then
        continue
    fi

    echo "i : $i"
done

# ----------------------------------------------------------
# 4 continue n 命令结束指定循环
# 若不指定n,则默认结束1层循环
for (( i = 1; i <= 5; i++ )) # 第 3 层循环
do
    echo "i : $i ---"

    for (( j = 1; $j <= 5; j++ )) # 第 2 层循环
    do
        echo "j : $j --"

        for ((k = 1; $k <= 5; k++)) # 第 1 层循环
        do
            echo "k : $k"

            if [ $k -eq 2 ]
            then
                continue 2 # 结束第 2 层循环
            fi
        done
    done
done

【a】 本文部分内容参考自《Linux命令行与shell脚本编程大全 (第3版)》第13章

相关推荐
满怀101531 分钟前
Python扩展知识详解:lambda函数
开发语言·python
佚名涙1 小时前
go中锁的入门到进阶使用
开发语言·后端·golang
猫猫的小茶馆1 小时前
【PCB工艺】软件是如何控制硬件的发展过程
开发语言·stm32·单片机·嵌入式硬件·mcu·51单片机·pcb工艺
勘察加熊人2 小时前
wpf+c#路径迷宫鼠标绘制
开发语言·c#·wpf
小黄人软件3 小时前
C# ini文件全自动界面配置:打开界面时读ini配置到界面各控件,界面上的控件根据ini文件内容自动生成,点保存时把界面各控件的值写到ini里。
开发语言·c#
Android洋芋6 小时前
C语言深度解析:从零到系统级开发的完整指南
c语言·开发语言·stm32·条件语句·循环语句·结构体与联合体·指针基础
bjxiaxueliang6 小时前
一文详解QT环境搭建:Windows使用CLion配置QT开发环境
开发语言·windows·qt
Run_Teenage7 小时前
C语言 【初始指针】【指针一】
c语言·开发语言
苹果.Python.八宝粥7 小时前
Python第七章02:文件读取的练习
开发语言·python
J不A秃V头A7 小时前
Redis批量操作详解
开发语言·redis