Shell 脚本生成或打印数字范围(循环的数字序列)
我们的一位读者问:
如何在 BASH 的循环命令下生成一系列数字?例如,我需要在循环内运行特定命令 100 或 500 次。基本上,我想要一个从 FROM到TO计数的函数,例如 50-10 之类的数字。
要打印一系列数字,请使用 GNU 或 Unix seq 命令。在过去,我们使用自己的 shell 脚本。但现在不再使用肮脏的 shell 脚本;只需使用好的 seq 命令。在编写需要使用循环的数字范围的 shell 脚本时,这非常方便。Bash 还为这类东西提供了内置支持。
seq 命令语法用于生成或打印数字范围
语法如下:
seq LAST seq FIRST LAST seq FIRST INCREMENT LAST
换句话说,如果省略FIRST或INCREMENT,则默认为 1。也就是说,INCREMENT即使LAST小于,省略也默认为 1。FIRST因此FIRST,、INCREMENT和LAST被解释为浮点值。如果小于,则INCREMENT通常为正,如果 FIRST 大于 LAST,则通常为负。这听起来可能不太简单。因此,请尝试以下示例以理清思路。FIRSTLASTINCREMENT
示例
打开 Linux 或 Unix 终端,然后输入以下命令:
$ seq 5
示例输出:
1 2 3 4 5
再举几个例子:
$ seq 5 10
$ seq 0 2 10
$ seq 5 -1 1
seq 命令和 shell 脚本(for 循环)
您可以在bash 的 for 循环中使用 seq 命令,如下所示:
#!/bin/bash for i in $(seq 5) do echo "Welcome $i times" done
在 shell 脚本中使用 bash 括号扩展来生成数字序列
括号扩展允许您通过在花括号 {} 内指定模式来生成一系列字符串。模式 {1..3} 表示“从 1 扩展到 3”,Bash 将生成以下序列:
$ echo {1..3}
或
$ printf "%d\n" {1..3}
echo 命令/printf 命令命令用于将输出打印到 Linux 或 Unix 终端。因此,当您运行该命令时,它将显示从 1 到 3 的数字序列,每个数字之间都用空格分隔。输出将如下所示:
1 2 3
使用 printf 进行如下或操作:
1 2 3
Bash for 循环生成数字序列
您还可以使用bash for 循环,如下所示:
#!/bin/bash for ((a=1; a <= 5 ; a++)) do echo "Welcome $a times." done
现实世界经验
#!/bin/bash # Script to move topics from old shared hosting to new lighttpd vps server # U="http://forum.example.com/viewtopic.php?t=" rdu="" for n in $(seq 1 521) do rdu="$(lynx --dump $U$n | egrep "vt([0-9]+)\.html$" | awk '{ print $2}' | uniq)" if [ "$rdu" == "" ]; then : else echo "$n => \"$rdu\"," fi rdu="" done
上述脚本生成一个新的 php 代码(数组)以与变量 t 匹配,以便我们可以发送 301 重定向。因此,任何访问旧论坛 url 的人http://www.example.com/example/forum/viewtopic.php?t=513都将被重定向到http://forum.example.com/linux-my-laptop-computer-unable-to-power-off-when-i-shutdown-vt513.html。接下来,我只需将 shell 脚本生成的数组复制并粘贴到 viewtopic.php 中,所有用户都会重定向到带有 301 http 代码的新 url。
<?php $URLS = array ( .... .. 3 => "http://forum.example.com/mysql-cluster-vt3.html", 4 => "http://forum.example.com/nice-look-and-feel-vt4.html", 5 => "http://forum.example.com/squid-monitoring-using-mrtg-vt5.html" .... ); $top=$_GET['t']; $u=$URLS[$top]; if ( isset($u)) { @include_once("../../include.genlib.php"); movePage(301, "$u"); } else { @include_once("../../include.genlib.php"); movePage(301, "http://forum.example.com"); } ?>
设置步长值并生成序列号
万一,您对我的旧的(也许是脏的) shell 脚本感兴趣????
#!/bin/bash # Usage: # ./script 1 5 + # ./script 100 50 - # where START END +/- FROM=$1 TO=$2 ACTION="$3" if [ "$ACTION" == "+" ]; then while [ $FROM -le $TO ] do echo -n $FROM " " (( FROM++ )) done echo "" else while [ $FROM -ge $TO ] do echo -n $FROM " " (( FROM-- )) done echo " " fi
$ chmod +x script
$ ./script 5 10 +
$ ./script 20 10 -
使用变量
使用读取命令从键盘获取输入:
#!/bin/bash read -r -p "Type a number: " number echo "Print 1 to ${number} using seq command ..." seq 1 $number echo "Print 1 to ${number} using bash Brace Expansion ..." eval echo "{1..${number}}"
此脚本将提示您输入一个数字。输入数字后,代码将打印从 1 到您输入的数字:
seq 1 $number
最后,括号扩展允许您将一系列数字扩展为列表。括号扩展的语法是:
{start..end}
起始值和结束值可以是任意数字。..运算符表示序列应包含从起始到结束的所有数字(含起始和结束)。eval 命令用于评估 bash 表达式。例如,此脚本中使用 eval 命令评估表达式 echo " {1..${number}"。echo 命令会将表达式的结果打印到 Linux 或 Unix 终端窗口。
总结
您可以使用 shell 脚本中的 seq 命令和 bash 括号扩展来生成或打印数字范围。语法是
seq START END seq FIRST INCREMENT LAST seq 1 10 seq 5 10 seq 2 2 10 echo {START..END} for i in {5..10} do echo "$i" done
有关更多信息,请使用 man 命令或 help 命令查看以下文档:
$ man bash
$ man seq
$ help for
$ seq --help