服务器 频道

AWK :Linux 管理员的智能工具包(中)

  花括号和字段分隔符

  括号字符在 AWK 命令中起着很重要的作用。出现在括号之间的操作指出将要发生什么以及何时发生。当只使用一对括号时:

  {print $3,$2}

  括号间的所有操作同时发生。当使用多于一对的括号时:

  {print $3}{print $2}

  执行第一组命令,在该命令完成后执行第二组命令。注意以下两列清单的区别:

  $ awk ''{print $3,$2}'' names

  EVAN DULANEY

  JEFF DURHAM

  BILL STEEN

  EVAN FELDMAN

  STEVE SWIM

  ROBERT BOGUE

  MICAH JUNE

  SHERYL KANE

  WILLIAM WOOD

  SARAH FERGUS

  SARAH BUCK

  BOB TUTTLE

  $

  

  $ awk ''{print $3}{print $2}'' names

  EVAN

  DULANEY

  JEFF

  DURHAM

  BILL

  STEEN

  EVAN

  FELDMAN

  STEVE

  SWIM

  ROBERT

  BOGUE

  MICAH

  JUNE

  SHERYL

  KANE

  WILLIAM

  WOOD

  SARAH

  FERGUS

  SARAH

  BUCK

  BOB

  TUTTLE

  $

  要利用多组括号进行重复查找,执行第一组中的命令直到完成为止;然后处理第二组命令。如果有第三组命令,则在第二组命令完成后执行它,以此类推。在所生成的打印输出中,有两个分隔的打印命令,因此先执行第一个命令,随后执行第二个命令,这样导致每个条目显示在两行而不是一行中。

  区分两个字段的字段分隔符不一定始终是空格;它可以是任何可识别的字符。为进行演示,假定 emp_names 文件利用冒号而不是制表符来分隔字段:

  $ cat emp_names

  46012:DULANEY:EVAN: MOBILE : AL

  46013: DURHAM :JEFF: MOBILE : AL

  46015:STEEN:BILL: MOBILE : AL

  46017:FELDMAN:EVAN: MOBILE : AL

  46018:SWIM:STEVE:UNKNOWN: AL

  46019:BOGUE:ROBERT: PHOENIX :AZ

  46021:JUNE:MICAH: PHOENIX :AZ

  46022:KANE:SHERYL:UNKNOWN:AR

  46024:WOOD:WILLIAM: MUNCIE :IN

  46026:FERGUS:SARAH: MUNCIE :IN

  46027:BUCK:SARAH: MUNCIE :IN

  46029:TUTTLE:BOB: MUNCIE :IN

  $

  如果试图通过指定所需要的第二个字段来打印姓氏

  $ awk ''{print $2}'' emp_names

  您最后会得到十二个空行。因为文件中没有空格,除了第一个字段之外没有可认别的字段。为解决这一问题,必须通知 AWK 是空格之外的另一个字符作为分隔符,有两种方法可通知 AWK 使用新的字段分隔符:使用命令行参数 -F ,或在程序中指定变量 FS 。两种方法的效果相同,只有一种例外情况,如下例所示:

  $ awk ''{FS=":"}{print $2}'' emp_names

  

  DURHAM

  STEEN

  FELDMAN

  SWIM

  BOGUE

  JUNE

  KANE

  WOOD

  FERGUS

  BUCK

  TUTTLE

  $

  

  $ awk -F: ''{print $2}'' emp_names

  DULANEY

  DURHAM

  STEEN

  FELDMAN

  SWIM

  BOGUE

  JUNE

  KANE

  WOOD

  FERGUS

  BUCK

  TUTTLE

  $

  在第一个命令中,头一条记录返回不正确的空行,而其他结果正确。直到读取第二条记录时,才识别字段分隔符并正确地执行。通过使用 BEGIN 语句可以纠正这一缺点(在后文详述)。 -F 的功能非常类似于 BEGIN ,能够正确地读取第一条记录并按要求执行。

  在本文开始处我曾提到,默认的显示 / 输出字段分隔符是空格。通过使用输出字段分隔符 ( OFS ) 变量,可以在程序中更改此特性。例如,要读取文件(由冒号分隔)并以短划线显示,则命令是

  $ awk -F":" ''{OFS="-"}{print $1,$2,$3,$4,$5}'' emp_names

  46012-DULANEY-EVAN-MOBILE-AL

  46013-DURHAM-JEFF-MOBILE-AL

  46015-STEEN-BILL-MOBILE-AL

  46017-FELDMAN-EVAN-MOBILE-AL

  46018-SWIM-STEVE-UNKNOWN-AL

  46019-BOGUE-ROBERT-PHOENIX-AZ

  46021-JUNE-MICAH-PHOENIX-AZ

  46022-KANE-SHERYL-UNKNOWN-AR

  46024-WOOD-WILLIAM-MUNCIE-IN

  46026-FERGUS-SARAH-MUNCIE-IN

  46027-BUCK-SARAH-MUNCIE-IN

  46029-TUTTLE-BOB-MUNCIE-IN

  $

  FS 和 OFS 是(输入)字段分隔符和输出字段分隔符,它们只是一对可以在 AWK 实用工具中使用的变量。例如,要在打印时为每行编号,可以采用以下方式使用 NR 变量:

  $ awk -F":" ''{print NR,$1,$2,$3}'' emp_names

  1 46012 DULANEY EVAN

  2 46013 DURHAM JEFF

  3 46015 STEEN BILL

  4 46017 FELDMAN EVAN

  5 46018 SWIM STEVE

  6 46019 BOGUE ROBERT

  7 46021 JUNE MICAH

  8 46022 KANE SHERYL

  9 46024 WOOD WILLIAM

  10 46026 FERGUS SARAH

  11 46027 BUCK SARAH

  12 46029 TUTTLE BOB

  $

  找出员工号码处于 46012 和 46015 之间的所有行:

  $ awk -F":" ''/4601[2-5]/'' emp_names

  46012 DULANEY EVAN MOBILE AL

  46013 DURHAM JEFF MOBILE AL

  46015 STEEN BILL MOBILE AL

  $

0
相关文章