我如何在bash中编写for循环


Answers:


103

从此站点

for i in $(seq 1 10);
do
    echo $i
done

10
值得一提的是,此处指定的范围是包含在内的。这样,我的意思是您将看到打印到控制台的整个范围(1到10)。
杰米


34

bash for由变量(迭代器)和迭代器将要迭代的单词列表组成。

因此,如果您的单词列表很有限,只需将它们放在以下语法中:

for w in word1 word2 word3
do
  doSomething($w)
done

可能您想遍历一些数字,因此可以使用该seq命令为您生成数字列表:(例如,从1到100)

seq 1 100

并在FOR循环中使用它:

for n in $(seq 1 100)
do
  doSomething($n)
done

注意$(...)语法。这是一种bash行为,它允许您将输出从一个命令(在我们的例子中是从seq)传递到另一个命令(在for

当您必须遍历某个路径中的所有目录时,这非常有用,例如:

for d in $(find $somepath -type d)
do
  doSomething($d)
done

生成列表的可能性是无限的。


2
很好的答案,但是您可能要包括for((i = 0; i <MAX; i ++)); 做doSomething($ i); 完成变体。我认为这通常优于$(seq 0 MAX)变体中的for i,因为后者在实际执行循环之前会首先生成从0到MAX的所有数字。
mweerden

30

Bash 3.0+可以使用以下语法:

for i in {1..10} ; do ... ; done

..避免生成外部程序来扩展序列(例如seq 1 10)。

当然,这与for(())解决方案具有相同的问题,与bash甚至特定版本绑定(如果这对您很重要)。


14

尝试bash内置的帮助:


$ help for

for: for NAME [in WORDS ... ;] do COMMANDS; done
    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
    Equivalent to
        (( EXP1 ))
        while (( EXP2 )); do
            COMMANDS
            (( EXP3 ))
        done
    EXP1, EXP2, and EXP3 are arithmetic expressions.  If any expression is
    omitted, it behaves as if it evaluates to 1.


5
#! /bin/bash

function do_something {
   echo value=${1}
}

MAX=4
for (( i=0; i<MAX; i++ )) ; {
   do_something ${i}
}

这是一个示例,它也可以在较旧的shell中工作,同时仍然可以有效地处理大量的示例:

Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'

但是,祝您好运awk在awk脚本中如何使用shell变量?


2
我之前没有注意到,但是在较早的答案之一中显示了类似的语法。这里的独特之处是使用花括号而不是典型的do/ done
布伦特·布拉德本

4

我通常喜欢在标准的for循环上使用一个轻微的变体。我经常使用它在一系列远程主机上运行命令。我利用bash的大括号扩展来创建for循环,这使我可以创建非数字的for循环。

例:

我想在前端主机1-5和后端主机1-3上运行uptime命令:

% for host in {frontend{1..5},backend{1..3}}.mycompany.com
    do ssh $host "echo -n $host; uptime"
  done

我通常将其作为单行命令运行,并在行尾加上分号,而不是上面更易读的版本。关键的使用注意事项是:大括号允许您指定要插入字符串中的多个值(例如,在prefoopost,prebarpost中的pre {foo,bar} post结果),并可以使用双倍句号(可以使用a)来计数/序列。 .z等)。但是,双周期语法是bash 3.0的新功能;早期版本将不支持此功能。


与此相关的是,如果$ host var由于偶然而为空行怎么办?它仍然会触发ssh。那么,如何避免这种情况呢?就我而言,我正在做其他事情,因此您的回答将对我有所帮助。我正在尝试检查Gmail中是否有新邮件,如果找到,则发送来自和主题的短信。如果您想阅读,我的问题被标记为“连接两个Bash命令”。
Volomike

我不相信您会得到一个空的$ host var。这是因为上面的示例正在使用大括号扩展。for循环将$ host变量显式设置为以下值:frontend1.mycompany.com frontend2.mycompany.com。。backend1.mycompany.com但是,如果您看到一种使其具有null值的方法,则该方法无效。我很想知道。如果有问题,可以在条件测试中执行ssh。
terson

1

如果您只对bash感兴趣,那么上面介绍的“ for((... ...))”解决方案是最好的,但是如果您希望POSIX SH兼容的东西可以在所有unice上工作,则必须使用“ expr”, “ while”,这是因为“((())””或“ seq”或“ i = i + 1”在各种外壳之间不那么可移植


0

我一直使用这种变体来处理文件...

用于* .log中的文件;回显“使用以下命令执行操作:$ files”;echo“使用$ files做更多的事情”; 完成

如果您感兴趣的是处理文件列表,请查看-execdir选项以获得files


我认为您的意思是-execdir选项,用于查找
已暂停,直到另行通知。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.