for

for循环的使用。比如,想要固定次数的循环,或者循环某个文件中的类容等等。while是另外一种循环方式。

背景知识

在shell中,定义字符串,不需要用字符串来界定,比如:echo hello worldmyshell.sh 参数1 参数2 参数3

所以,脑海里面,一定要纠正观念,在shell中定义字符串不需要引号。出现引号,其实为了保护定义的内容,别过早的解析、或变量被解析。单引号:变量不会被解析。双引号,变量会被解析。单双引号,都会将带空格分隔的内容,视为一个整体(有时候接收的某个参数包含空格或星号等,则需要用引号包裹,保护,避免解析。如果该参数再内部使用的时候,不加引号,则空格的分隔会让它变为多个参数、星号则会被解析)。

for核心语法:

for each in java c php;do
    echo $each
done

注意上面是没有用任何引号来定义的字符串。如果加了,则返回视为一个整体。如:

# 输出一行
for each in 'java c php';do
    echo $each
done

# 多行
# 如要纠正,再次引用的时候,失去引号保护即可:
lang='java c php'
for each in $lang;do
    echo $each
done

基于以上的理解,我们可以理解:in的后面,可以跟任何可以被shell解析的命令,或表达式。比如:

for each in express;do
    echo $each
done


# express可以有如下:
{1..10}
echo {1..10}{2,3}  # 或括号是shell来解析的。

# 命令
`cat myfile.sh`  
# 路径
demo/*.php   # 或包装成命令   `ls demo/*.php`

# 其他的,如  ?  * 等都

固定次数循环

C语言风格

for ((i=1; i<=100; i++))
do
  echo $i
done

Python风格(in的使用)

for ((i=1; i<=100; i++))
do
  echo $i
done

Seq的使用

for i in `seq 1 1000`
   do curl -s -o /dev/null "http://$GATEWAY_URL/count";
done

字符串

首先,要明白,它会自动以空格,来区分每个元素,类似与awk中的默认分隔选项(个人感觉)。所以,如果line中如果有空格,则会被拆分几个部分。

for line in $(cat some.txt);do
    echo $line
done

复杂一点的例子。

for line in $(docker image ls |grep examples-bookinfo|awk '{print $1,$2,$3}' |sed 's/\s/__/g');do
    image=$(echo $line|awk -F '__' '{print $1}')
    tag=$(echo $line|awk -F '__' '{print $2}')
    imageid=$(echo $line|awk -F '__' '{print $3}')
    imagenew=$(echo $image|sed 's/10.131.9.12:5000/docker.io/g')
    docker tag "$image:$tag" "$imagenew:$tag"
done

输入的参数:

for i in $* ;  
do  
	echo $i is input chart\! ;  
done 

直接变量(字符串)

重点:下面是本质,不带引号。任何其他命,相当于先执行,然后间接生成这个。

for i in f1 f2 f3;do
    echo $i is appoint;
done 

#等效于下面
line="f1 f2 f3"
for i in $line;do 
    echo $i is appoint;
done 
#但是不能直接使用下面
#for i in "f1 f2 f3";do 

路径

for file in /proc/*;  # 或 *.sh
do
    echo $file;
done

# 实际上等价于   for file in $(ls /proc/*);do echo $file;done

序列

{1..10} 本身会被shell展开。

for n in {1..10}
do
    echo $n
done

组合

使用多个{}来进行组合,中间可以有链接符号,但是不能有空格。

#!/bin/bash
for i in {linux,darwin,freebsd,windows}/{amd64,386}
do
	echo $i
done

echo "----------"
for i in {5,6,8}{c,g,a,l}
do
    echo $i
done

echo "----------"
# for i in {5,6,8} is {c,g,a,l}  # 注意连接符号有空格,则是另外一种情况。
for i in {5,6,8}is{c,g,a,l}
do
    echo $i
done

echo "----------"

for i in {5,6,8}:{c,g,a,l}:{t,b}
do
    echo $i
done

字符串的保护

files=`ls`
# 输出单行
echo $files
# 保护下,输出多行
echo "$files"

# 多个
for n in $files;do echo $n;echo '#';done
# 保护下,居然成了一个
for n in "$files";do echo $n;echo '#';done
# in 后面 如果是个字符串,怎么都会变成一个。