linux-循环

版权声明:来一来,看一看,有钱的捧个人场,没钱的你不得捧个人场 https://blog.csdn.net/wait_for_eva/article/details/84550847

seq

seq 10

运行一下就知道了,和pythonrange一样

参数 含义 作用
start 序列起始 定义起始
end 序列结束 定义结束
step 步进 序列间隔
  • 顺序

两者参数顺序相同。

单个参数时,表示的是end

两个参数时,表示的是(start, end)

三个参数时,表示的是(start, step, end)

  • 首尾
参数 seq range
start 默认从1开始 默认从0开始
end 默认包含 默认不包含
end -step
  • 步进

两者一致。

# 1,3,5,7,9
seq 1 2 9
# 1,2,3,4,5,6,7,8,9
seq 9
seq 1 9
  • 简略

如果不指定step,用{start..end}更加方便。

seq {}
start -
seq start end {start..end}
seq start step end {start..end..step}

{}也不仅是seq,它能够自动打开。

之前说过的mkdir {a,b}_{c,d}就是如此。

for

模式

for var in vars;
do
    statements
    ...
done

遍历

  • 枚举
#!/bin/bash
for var in 1 2 3 4 5;
do
    echo $var
done
  • 序列
#!/bin/bash
for var in {1..9};
do
    echo $var
done
echo "--------------------"
for var in `seq 9 -1 1`;
do
    echo $var
done
  • 命令
#!/bin/bash
for dir in `ls /etc/`;
do
    echo $dir
done
  • 路径
#!/bin/bash
for dir in /etc/*;
do
    echo $dir
done

分隔

  • 参数
#!/bin/bash
for param in $*;
do
    echo $param
done
  • 字符
#!/bin/bash
vars="a b c d e f g"
for var in $vars;
do
    echo $var
done
  • 自定
#!/bin/bash
OLD_IFS=$IFS
IFS=";"
vars="a;b;c;d;e;f;g"
for var in $vars;
do
    echo $var
done
IFS=$OLD_IFS

通过环境变量IFS进行字符分隔,然后遍历。

命令结果的遍历可以理解为IFS=\n的结果,不过细节不同。

我们不得不熟悉IFS,因为有些时候我们需要指定分隔符,有时候却要避免。

#!/bin/bash

for line in `ls -lhi /etc`;
do
   echo $line
done

你会发现结果和你所想不太一致,因为IFS默认

#!/bin/bash
OLD_IFS=$IFS
$IFS=";"
for line in `ls -lhi /etc/`;
do
    echo $line
done
IFS=$OLD_IFS

这样就ok了,当然,也可以当做split进行使用。

#!/bin/bash
OLD_IFS=$IFS
IFS=$2
for part in $1;
do
    echo $part
done
IFS=$OLD_IFS

定界

#!/bin/bash
for((i=1;i<10;i++));
do
    echo $i
done
  • 界限

前面的都是枚举的遍历,没有所谓的动态边界。

(())for,更贴合我们的代码习惯,也引入了条件限制。

while

模式

while expression;
do
    statement
    ...
done

条件

#!/bin/bash
i=10
while((i-->0));
do
    echo $i
done

continue

#!/bin/bash
i=10
while((i-->0));
do
    if ((i%2==0));then
        continue
    fi
    echo $i
done

break

#!/bin/bash
i=0
while((1));do
    if ((i>=100));then
        break
    else
        ((i+=1))
    fi
    if ((i%2==0));then
        continue
    fi
    echo $i
done

(())

对于()(())[][[]],都会感觉到模棱两可。

借助$(($A+$B))或许可见一斑。

首先,得明白第一个$的含义,总结起来,$就是用来取变量名所存储的值的。

也就是说,(($A+$B))返回的不过是一个变量,好比方法,不过是匿名的。

(())[[]]都是脚本开的子进程,然后子进程进行执行。

更主要的是

#!/bin/bash
a=1
b=2
echo $(($a+$b))
echo $((a+b))

输出结果是一致的,为什么。

更多的我暂时也说不出,但是,明白的一点就是,我们可以不再那么繁琐。

翻译一下所谓的$(($a+$b)),就是$((1+2))

也就是说,在(())内部,我们所使用的,是进一步的操作。

直接的数值就是数值,直接的变量就是变量,(())进行数值计算,[[]]进行字符的计算。

而且,++--等操作可以直接进行。

(())中,就好比了高级语言的编程。

所以,要跳出$(($a+$b))的陷阱,也不要在(())中继续$的操作。

因为直接计算1+2是必定可以的,但是1+=2是明显的错误。

shell中的所谓变量,和高级语言中的变量差异不小,在(())中的是高级语言计算。

until

模式

until expression;do
    statement
    ...
done

例子

#!/bin/bash
i=0
until((i++>100));
do
    if ((i%2 ==0));then
        continue
    fi
    echo $i
done

(())中尽情施展吧,高级语言可不是难事。

while是满足expression然后执行statement

unitl是执行statement直到满足expresstion

简而言之,一个满足才行动,一个不满足才行动。

脚本

sum

#!/bin/bash
sum=0
for value in $*;do
    ((sum+=value))
done
echo "sum : $sum"

其中的((sum += value))也可以换成(( sum += $value))

不过是变量运算变成了直接的手动数值加减。

但是绝对不能$sum,因为sum必须保证是变量,普通数值不具备存储功能。

gfind

#!/bin/bash
if [ -d $1 ];then
    dir=$1/*
else
    dir=$1
fi
for file in $dir;do
    if [ -d $file ];then
        ./find $file $2
    else
        line=`cat $file -n | grep $2 | sed -r 's/^ +//g' |sed -r 's/^([0-9]+).*$/\1/'`
    fi
    if (( line != 0 ));then
        echo $file   $line   `sed -n "${line}p" $file `
    fi
done

在指定目录下,根据文件内容查文件。

输出文件名, 行号, 行内容

对于脚本而言,循环的作用就是把单操作扩展到其他对象上。

不仅是数据,文件,或者更多。

把单次的重复简略化,批处理更快捷。

猜你喜欢

转载自blog.csdn.net/wait_for_eva/article/details/84550847