循环处理文件数据
循环处理文件数据时通常必须遍历存储在文件中的数据,这要求结合已经讲过的两种技术:
1、使用嵌套循环
2、修改IFS环境变量
通过修改IFS环境变量,就能强制for命令将文件中的每行都当成单独的一个条目来处理,即便数据中有空格也是如此。一旦从文件中提取出了单独的行,可能需要再次利用循环来提取行中的数据。
典型的例子是处理/etc/passwd文件中的数据。这要求你逐行遍历/etc/passwd文件,并将IFS变量的值改为冒号,这样就可以分隔开每行中的各个数据段了。
1:首先我们先用less命令查看一下/etc/passwd文件,方便等会做比较
[chendajie@CHENDAJIE ChangeIFS]$ less -N /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
...
2:编写脚本文件如下:
[chendajie@CHENDAJIE ChangeIFS]$ cat -n test1
1 #!/bin/bash
2 # Changing the IFS value
3
4 IFS.OLD=$IFS
5 IFS=$'\n'
6 for entry in $(cat /etc/passwd)
7 do
8 echo "Values in $entry -"
9 IFS=:
10 for value in $entry
11 do
12 echo " $value"
13 done
14 done
这个脚本使用了两个不同的IFS值来解析数据。第一个IFS值解析出/etc/passwd文件中的单独的行,内部循环接着将IFS的值修改为冒号,允许你从/etc/passwd的行中解析出单独的值。
3:执行文件并显示:
[chendajie@CHENDAJIE ChangeIFS]$ ./test1 | less -N
./test1:行4: IFS.OLD=: 未找到命令
1 Values in root:x:0:0:root:/root:/bin/bash -
2 root
3 x
4 0
5 0
6 root
7 /root
8 /bin/bash
9 Values in bin:x:1:1:bin:/bin:/sbin/nologin -
...
内部循环会解析出/etc/passwd每行中的各个值。这种方法在处理外部导入电子表格所采用的逗号分隔的数据时也会很方便。
Linux中的IFS环境变量
1、IFS定义
Linux下有一个特殊的环境变量叫做IFS,叫做内部字段分隔符(internal field separator)。IFS环境变量定义了bash shell用户字段分隔符的一系列字符。默认情况下,bash shell会将下面的字符当做字段分隔符:空格、制表符、换行符。
2、IFS修改
Bash shell会将上面的三个字符当做列表中新字段的开始。例如,1 2 3字符串在shell中会当做三个字段1,2,3。如果想要以逗号分隔字段,则要修改IFS的值,修改如下:
IFS=','