Shell 字段分隔符与迭代器

Shell 字段分隔符与迭代器内部字段分隔符(Internal Field Separator,IFS)是shell脚本编程中的一个重要概念。在处理文本数据时,它的作用可不小。
作为分隔符,IFS有其特殊用途。它是一个环境变量,其中保存了用于分隔的字符。它是当前shell环境使用的默认定界字符串。
考虑一种情形:我们需要迭代一个字符串或逗号分隔型数值(Comma Separated Value,CSV)中的单词。如果是前者,可以使用IFS=" ";如果是后者,则使用IFS=","

Shell字段分隔符与迭代器

预备知识

考虑CSV数据的情况:

data="name, gender,rollno,location"

我们可以使用IFS读取变量中的每一个条目。

oldIFS=IFS
IFS=,     #IFS现在被设置为,
for item indata;
do
    echo Item: item
done

IFS=oldIFS

输出如下:

Item: name
Item: gender
Item: rollno
Item: location

IFS的默认值为空白字符(换行符、制表符或者空格)。
当IFS被设置为逗号时,shell将逗号视为一个定界符,因此变量$item在每次迭代中读取由逗号分隔的子串作为变量值。
如果没有把IFS设置成逗号,那么上面的脚本会将全部数据作为单个字符串打印出来。

实战演练

让我们以/etc/passwd为例,看看IFS的另一种用法。在文件/etc/passwd中,每一行包含了由冒号分隔的多个条目。该文件中的每行都对应着某个用户的相关属性。
考虑这样的输入:root:x:0:0:root:/root:/bin/bash。每行的最后一项指定了用户的默认shell。
可以按照下面的方法巧妙地利用IFS打印出用户以及他们默认的shell:

#!/bin/bash
#用途: 演示IFS的用法
line="root:x:0:0:root:/root:/bin/bash"
oldIFS=IFS;
IFS=":"
count=0
for item inline;
do

     [ count -eq 0 ]  && user=item;
     [ count -eq 6 ]  && shell=item;
    let count++
done;
IFS=oldIFS
echouser's shell is $shell;

输出为:

root's shell is /bin/bash

循环在对一系列值进行迭代时非常有用。Bash提供了多种类型的循环。

  • 面向列表的for循环
for var in list;
do
    commands;    #使用变量$var
done

list可以是一个字符串,也可以是一个值序列。
我们可以使用echo命令生成各种值序列:

echo {1..50};    #生成一个从1~50的数字序列
echo {a..z} {A..Z};    #生成大小写字母序列

同样,我们可以将这些方法结合起来对数据进行拼接(concatenate)。下面的代码中,变量i在每次迭代的过程里都会保存一个范围在a到z之间的字符:

for i in {a..z}; do actions; done;
  • 迭代指定范围的数字
for((i=0;i<10;i++))
{
   commands;    #使用变量$i
}
  • 循环到条件满足为止
    当条件为真时,while循环继续执行;当条件不为真时,until循环继续执行。
while condition
do
    commands;
done

true作为循环条件能够产生无限循环。

  • until循环在Bash中还可以使用一个特殊的循环until。它会一直循环,直到给定的条件为真。例如:
x=0;
until [ x -eq 9 ];    #条件是[x -eq 9 ]
do
    let x++; echo $x;
done

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程