1.6.5. 从文本文件的表格中提取数据

下面有一个文本文件 “DPL” ,里面含有 2004 年以前 Debian 项目的领导者名字和起始日期,并以空格分隔。

  1. Ian Murdock August 1993
  2. Bruce Perens April 1996
  3. Ian Jackson January 1998
  4. Wichert Akkerman January 1999
  5. Ben Collins April 2001
  6. Bdale Garbee April 2002
  7. Martin Michlmayr March 2003
[提示]提示

参见 “Debian 简史” 获取最新的 Debian 领导阶层历史

Awk 经常被用来从这种类型的文件中提取数据。

尝试下列例子

  1. $ awk '{ print $3 }' <DPL # month started
  2. August
  3. April
  4. January
  5. January
  6. April
  7. April
  8. March
  9. $ awk '($1=="Ian") { print }' <DPL # DPL called Ian
  10. Ian Murdock August 1993
  11. Ian Jackson January 1998
  12. $ awk '($2=="Perens") { print $3,$4 }' <DPL # When Perens started
  13. April 1996

Shell (例如 Bash )也可以用来分析这种文件。

尝试下列例子

  1. $ while read first last month year; do
  2. echo $month
  3. done <DPL
  4. ... 第一个 AWK 例子的一些输出

内建命令 read 使用 “$IFS” (内部域分隔符)中的字符来将行分隔成多个单词。

如果你将 “$IFS” 改变为 “:” ,你可以很好地使用 shell 来分析 “/etc/passwd”。

  1. $ oldIFS="$IFS" # save old value
  2. $ IFS=':'
  3. $ while read user password uid gid rest_of_line; do
  4. if [ "$user" = "bozo" ]; then
  5. echo "$user's ID is $uid"
  6. fi
  7. done < /etc/passwd
  8. bozo's ID is 1000
  9. $ IFS="$oldIFS" # restore old value

(如果要用 Awk 做到相同的事,使用 “FS=':'” 来设置域分隔符。)

IFS 也被 shell 用来分割参数扩展、命令替换和算术扩展的结果。这不会出现在双引号或单引号中。 IFS 的默认值为 <空格>、<tab> 和<换行符>。

请谨慎使用 shell 的 IFS 技巧。当 shell 将脚本的一部分解释为对它的输入时,会发生一些奇怪的事。

  1. $ IFS=":," # use ":" and "," as IFS
  2. $ echo IFS=$IFS, IFS="$IFS" # echo is a Bash builtin
  3. IFS= , IFS=:,
  4. $ date -R # just a command output
  5. Sat, 23 Aug 2003 08:30:15 +0200
  6. $ echo $(date -R) # sub shell --> input to main shell
  7. Sat 23 Aug 2003 08 30 36 +0200
  8. $ unset IFS # reset IFS to the default
  9. $ echo $(date -R)
  10. Sat, 23 Aug 2003 08:30:50 +0200