Linux&shell之结构化命令进阶

简介:

 for命令
重复一系列的命令是一种常见的编程实践。

复制代码
#!/bin/bash
# basic for command
for test in A B C D E F G H I J K L M N O P Q
do
  echo The next letter is $test
done
复制代码

结果:
The next letter is A
The next letter is B
The next letter is C
The next letter is D
The next letter is E
The next letter is F
The next letter is G
The next letter is H
The next letter is I
The next letter is J
The next letter is K
The next letter is L
The next letter is M
The next letter is N
The next letter is O
The next letter is P
The next letter is Q

每次for命令将列表中的下一个值赋值给变量test。变量testfor使使test可以像for命令语句中使用其他脚本变量一样使用。最后一次迭代之后,变量test在shell脚本的其他部分中仍然有效。它仍然是迭代的最后一个值。
如下:

复制代码
#!/bin/bash
# basic for command
for test in A B C D
do
  echo The next letter is $test
done
echo "The last letter is $test"
test=Z
echo "Wait,now the letter is $test"
复制代码

结果:
The next letter is A
The next letter is B
The next letter is C
The next letter is D
The last letter is D
Wait,now the letter is Z

单引号会引起问题,如下所示

复制代码
#!/bin/bash
# basic for command
for test in I don't know if this'll work
do
  echo "word:$test"
done
复制代码

结果:
word:I
word:dont know if thisll
word:work
由于单引号的存在出现问题了,有两种方法解决这个问题:
使用转义字符\来转义单引号;
或使用双引号来定义使用单引号的值。
两种方法都不是很好。

复制代码
#!/bin/bash
# basic for command
for test in I don\'t know if this\'ll work
do
  echo "word:$test"
done
或
#!/bin/bash
# basic for command
for test in I "don't" know if "this'll" work  
do
  echo "word:$test"
done
复制代码

如果有的数据之间有空格,可以通过双引号括起来
如下:

复制代码
#!/bin/bash
# basic for command
for test in Nevada New Hampshire New Mexico New York North Carolina
do
  echo "Now going to $test"
done
复制代码

结果:
Now going to Nevada
Now going to New
Now going to Hampshire
Now going to New
Now going to Mexico
Now going to New
Now going to York
Now going to North
Now going to Carolina
但是这并不是我们想要到结果,解决办法

复制代码
#!/bin/bash
# basic for command
for test in Nevada "New Hampshire" "New Mexico" "New York" "North Carolina"
do
  echo "Now going to $test"
done
复制代码

结果:
Now going to Nevada
Now going to New Hampshire
Now going to New Mexico
Now going to New York
Now going to North Carolina

从变量读取列表

复制代码
#!/bin/bash
# using a variable to hold the list
list="Beijing Shanghai Guangzhou Shenzhen Nanjing Hangzhou"
list=$list" Suzhou"

for city in $list
do
  echo "Have you ever visited $city"
done
复制代码

结果:
Have you ever visited Beijing
Have you ever visited Shanghai
Have you ever visited Guangzhou
Have you ever visited Shenzhen
Have you ever visited Nanjing
Have you ever visited Hangzhou
Have you ever visited Suzhou

读取命令中的值
生成列表中使用的值的另一种方法是使用命令的输出。
如下:

复制代码
#!/bin/bash
# reading values from a file
file="cities"

for city in `cat $file`
do
  echo "Have you ever visited $city"
done
复制代码

文件cities中的内容
Nanjing
Shang hai
Beijing
Shenzhen
Suzhou
Guangzhou
结果:
Have you ever visited Nanjing
Have you ever visited Shang
Have you ever visited hai
Have you ever visited Beijing
Have you ever visited Shenzhen
Have you ever visited Suzhou
Have you ever visited Guangzhou

问题,这里有空格的话,就会被分成两个输出比如Shang hai 被分成了两个Shang 和hai
怎么解决呢?下面讲解
默认情况下,bash shell将下面的字符看作字段分隔符:空格,制表符,换行符
可以在shell脚本中暂时更改环境变量IFS的值。例如:

复制代码
#!/bin/bash
# reading values from a file
file="cities"

IFS=$'\n'
for city in `cat $file`
do
  echo "Have you ever visited $city"
done
复制代码

这个时候就会把空格排除在外了

使用通配符读取目录

复制代码
#!/bin/bash
#iterate through all the files in a directory

for file in /home/* /home/jiqing9006/shellscript/*
do
  if [ -d "$file" ]
  then
    echo "$file is a directory"
  elif [ -f "$file" ]
  then
    echo "$file is a file"
  fi
done
复制代码

结果:
/home/jiqing9006 is a directory
/home/lost+found is a directory
/home/test is a directory
/home/wghan is a directory
/home/jiqing9006/shellscript/cities is a file
/home/jiqing9006/shellscript/test1 is a file
/home/jiqing9006/shellscript/test10 is a file
/home/jiqing9006/shellscript/test11 is a file
...

C式的for命令

#!/bin/bash
#testing the C-style for loop
for((i=1;i<=10;i++))
do
  echo "The next number is $i"
done

使用多个变量

复制代码
#!/bin/bash
#testing the C-style for loop
for((a=1,b=10;a<=10;a++,b--))
do
  echo "$a-$b"
done
复制代码

结果:
1-10
2-9
3-8
4-7
5-6
6-5
7-4
8-3
9-2
10-1

复制代码
#!/bin/bash
#testing the C-style for loop
for((a=1,b=10;a<=10;a++,b--))
do
  echo $[ $a-$b ]
done
复制代码

这样就会计算值了

While循环

复制代码
#!/bin/bash
# while command test
var1=10
while [ $var1 -gt 0 ]
do
  echo $var1
  var1=$[ $var1 - 1 ]
done
复制代码


多条件

复制代码
#!/bin/bash
# while command test
var1=10
while echo $var1
      [ $var1 -gt 0 ]
do
  echo "This is inside the loop"
  var1=$[ $var1 - 1 ]
done
复制代码

结果
10
This is inside the loop
9
This is inside the loop
8
This is inside the loop
7
This is inside the loop
6
This is inside the loop
5
This is inside the loop
4
This is inside the loop
3
This is inside the loop
2
This is inside the loop
1
This is inside the loop
0

until命令
until命令刚好与while命令相反。until命令需要制定一条测试命令,这条命令通常产生一个非零的退出状态。
只要测试命令的退出状态非零,bash就会执行列在循环当中的命令。一旦为0,循环停止。

复制代码
#!/bin/bash
# using the until command
var1=100
until [ $var1 -gt 0 ]
do
  echo $var1
  var1=$[ $var1 -25 ]
done
复制代码

将不会执行,因为符合了大于0的条件,这个与while是相反的

嵌套循环

复制代码
#!/bin/bash
# nesting for loops
for((a = 1;a<=3;a++))
do
  echo "Starting loop $a:"
  for((b=1;b<=3;b++))
  do
    echo "Inside loop:$b"
  done
done
复制代码

(这里面空格就没那么重要了,都识别的)

结果:
Starting loop 1:
Inside loop:1
Inside loop:2
Inside loop:3
Starting loop 2:
Inside loop:1
Inside loop:2
Inside loop:3
Starting loop 3:
Inside loop:1
Inside loop:2
Inside loop:3

混合循环

复制代码
#!/bin/bash
# placing a for loop inside a while loop
var1=5
while [ $var1 -ge 0 ]
do
  echo "Outer loop:$var1"
  for((var2=1;var2<3;var2++))
  do
    var3=$[ $var1*$var2 ]
    echo "Inner loop:$var1*$var2 = $var3"
  done
  var1=$[$var1 -1]
done
复制代码

结果:
Outer loop:5
Inner loop:5*1 = 5
Inner loop:5*2 = 10
Outer loop:4
Inner loop:4*1 = 4
Inner loop:4*2 = 8
Outer loop:3
Inner loop:3*1 = 3
Inner loop:3*2 = 6
Outer loop:2
Inner loop:2*1 = 2
Inner loop:2*2 = 4
Outer loop:1
Inner loop:1*1 = 1
Inner loop:1*2 = 2
Outer loop:0
Inner loop:0*1 = 0
Inner loop:0*2 = 0

再来看一下until与while结合的,准备晕吧少年

复制代码
#!/bin/bash
#using until and while loops
var1=3
until [ $var1 -eq 0 ]
do
  echo "Outer loop:$var1"
  var2=1
  while [ $var2 -lt 5 ]
  do
    var3=`echo "scale=4;$var1/$var2"|bc`
    echo "  Inner loop:$var1/$var2 = $var3"
    var2=$[ $var2 +1 ]
  done
  var1=$[ $var1 - 1 ]
done
复制代码

#外循环执行三次,内循环每执行四次
结果:
Outer loop:3
  Inner loop:3/1 = 3.0000
  Inner loop:3/2 = 1.5000
  Inner loop:3/3 = 1.0000
  Inner loop:3/4 = .7500
Outer loop:2
  Inner loop:2/1 = 2.0000
  Inner loop:2/2 = 1.0000
  Inner loop:2/3 = .6666
  Inner loop:2/4 = .5000
Outer loop:1
  Inner loop:1/1 = 1.0000
  Inner loop:1/2 = .5000
  Inner loop:1/3 = .3333
  Inner loop:1/4 = .2500
控制循环
break&continue

复制代码
#!/bin/bash
# breaking out of a for loop

for var1 in 1 2 3 4 5 6 7 8 9 10
do
  if [ $var1 -eq 5 ]
  then
    break
  fi
  echo "number:$var1"
done
echo "The for loop is completed"
复制代码

同样适用于while循环

复制代码
#!/bin/bash
# breaking out of a while loop

var1=1

while [ $var1 -lt 10 ]
do
  if [ $var1 -eq 5 ]
  then
    break
  fi
  echo "number:$var1"
  var1=$[ $var1 + 1 ]
done
echo "The while loop is completed"
复制代码

(循环到等于5的时候,就停止了)

跳出内循环

复制代码
#!/bin/bash
# breaking out of an inner loop

for ((a=1;a<4;a++))
do
  echo "Outer loop:$a"
  for((b=1;b<100;b++))
  do
    if [ $b -eq 5 ]
    then
      break
    fi
    echo "  Inner loop:$b"
  done
done
复制代码

结果:
Outer loop:1
  Inner loop:1
  Inner loop:2
  Inner loop:3
  Inner loop:4
Outer loop:2
  Inner loop:1
  Inner loop:2
  Inner loop:3
  Inner loop:4
Outer loop:3
  Inner loop:1
  Inner loop:2
  Inner loop:3
  Inner loop:4
  (跳出了内部循环,但是外部循环继续进行)

跳出外部循环
break n,默认n是1,代表跳出当前循环。如果将n设置为2,将停止外循环的下一级循环。

复制代码
#!/bin/bash
# breaking out of an inner loop

for ((a=1;a<4;a++))
do
  echo "Outer loop:$a"
  for((b=1;b<100;b++))
  do
    if [ $b -eq 5 ]
    then
      break 2
    fi
    echo "  Inner loop:$b"
  done
done
复制代码

结果:
Outer loop:1
  Inner loop:1
  Inner loop:2
  Inner loop:3
  Inner loop:4
  (跳出了外部循环,当然本次的循环也终止了)

continue命令

复制代码
#!/bin/bash
# using the continue command

for((var1 = 1;var1<15;var1++))
do
  if [ $var1 -gt 5 ]&&[ $var1 -lt 10 ]
  then
    continue
  fi
  echo "Iteration number:$var1"
done
复制代码

结果:
Iteration number:1
Iteration number:2
Iteration number:3
Iteration number:4
Iteration number:5
Iteration number:10
Iteration number:11
Iteration number:12
Iteration number:13
Iteration number:14
(循环没有终止,只是跳过了,继续下一次循环)


复制代码
#!/bin/bash
# using the continue command

for((a=1;a<=5;a++))
do
  echo "Iteration $a:"
  for((b=1;b<=10;b++))
  do
    if [ $a -gt 3 ]&&[ $b -lt 5 ]
    then
      continue
    fi
    res=$[ $a*$b ]
    echo "The result of $a*$b is:$res"
  done
done
复制代码

(这个时候,会在a为4时或5时,的大循环中断掉b小于5的几个计算)

复制代码
#!/bin/bash
# using the continue command

for((a=1;a<=5;a++))
do
  echo "Iteration $a:"
  for((b=1;b<=10;b++))
  do
    if [ $a -gt 3 ]&&[ $b -lt 5 ]
    then
      continue 2
    fi
    res=$[ $a*$b ]
    echo "The result of $a*$b is:$res"
  done
done
复制代码

(这里直接跳过a为4或5的内循环,连b大于5的内容也不显示了)

复制代码
#!/bin/bash
# using the continue command

for((a=1;a<=5;a++))
do
  echo "Iteration $a:"
  for((b=1;b<=10;b++))
  do
    if [ $a -gt 3 ]&&[ $b -lt 5 ]
    then
      break
    fi
    res=$[ $a*$b ]
    echo "The result of $a*$b is:$res"
  done
done
复制代码

(跳出a为4或5的内循环,效果等同于continue 2)

复制代码
#!/bin/bash
# using the continue command

for((a=1;a<=5;a++))
do
  echo "Iteration $a:"
  for((b=1;b<=10;b++))
  do
    if [ $a -gt 3 ]&&[ $b -lt 5 ]
    then
      break 2
    fi
    res=$[ $a*$b ]
    echo "The result of $a*$b is:$res"
  done
done
复制代码

(直接跳出之后的动作,跳出外循环也终止了)

处理循环的输出

复制代码
#!/bin/bash
# using the continue command

for((a=1;a<=5;a++))
do
  echo "Iteration $a:"
  for((b=1;b<=10;b++))
  do
    if [ $a -gt 3 ]&&[ $b -lt 5 ]
    then
      break
    fi
    res=$[ $a*$b ]
    echo "The result of $a*$b is:$res"
  done
done > output.txt
复制代码

(会将循环得到的结果写入output.txt文档下)



本文转自TBHacker博客园博客,原文链接:http://www.cnblogs.com/jiqing9006/p/3200648.html,如需转载请自行联系原作者

相关文章
|
11天前
|
Web App开发 Linux 网络安全
工作中常用到的Linux命令
工作中常用到的Linux命令
|
11天前
|
Web App开发 Java Linux
Linux之Shell基本命令篇
Linux之Shell基本命令篇
Linux之Shell基本命令篇
|
8天前
|
NoSQL Linux Shell
常用的 Linux 命令
常用的 Linux 命令
30 9
|
1天前
|
安全 Linux 开发工具
Linux中可引起文件时间戳改变的相关命令
【4月更文挑战第12天】Linux中可引起文件时间戳改变的相关命令
8 0
|
2天前
|
域名解析 网络协议 Linux
Linux 中的 Nslookup 命令怎么使用?
【4月更文挑战第12天】
20 6
Linux 中的 Nslookup 命令怎么使用?
|
3天前
|
运维 网络协议 Unix
18.系统知识-Linux常用命令
18.系统知识-Linux常用命令
|
4天前
|
网络协议 Ubuntu Linux
Linux 下 TFTP 服务搭建及 U-Boot 中使用 tftp 命令实现文件下载
Linux 下 TFTP 服务搭建及 U-Boot 中使用 tftp 命令实现文件下载
|
4天前
|
Linux Go
Linux命令Top 100驱动人生! 面试必备
探索Linux命令不再迷茫!本文分10部分详解20个基础命令,带你由浅入深掌握文件、目录管理和文本处理。 [1]: <https://cloud.tencent.com/developer/article/2396114> [2]: <https://pan.quark.cn/s/865a0bbd5720> [3]: <https://yv4kfv1n3j.feishu.cn/docx/MRyxdaqz8ow5RjxyL1ucrvOYnnH>
48 0
|
6天前
|
分布式计算 Hadoop Shell
Hadoop【基础知识 04】【HDFS常用shell命令】(hadoop fs + hadoop dfs + hdfs dfs 使用举例)
【4月更文挑战第4天】Hadoop【基础知识 04】【HDFS常用shell命令】(hadoop fs + hadoop dfs + hdfs dfs 使用举例)
18 5
|
7天前
|
缓存 运维 监控
Linux系统监控利器:探索常用命令及数据保存技巧
Linux系统监控利器:探索常用命令及数据保存技巧
23 4
Linux系统监控利器:探索常用命令及数据保存技巧