如何使awk只在某些标题后运行?

时间:2011-12-04 19:53:18

标签: awk

我有一个文件,其中包含某些标题下的值表。像这样:

Series A
a 01 20
b 21 43
c 44 59
d 60 72

Series B
a 01 25
b 26 48
c 49 70
d 71 90

我的问题是,如何让awk只从指定的系列中提取信息?因此,如果告诉awk查看“B系列”第2列,它将输出该列。

3 个答案:

答案 0 :(得分:2)

如果数据用空行分隔,那么你可以使用类似的东西 -

[jaypal:~/Temp] cat file
Series A
a 01 20
b 21 43
c 44 59
d 60 72

Series B
a 01 25
b 26 48
c 49 70
d 71 90
[jaypal:~/Temp] awk '/Series B/,/^$/ { if (NF==3) print $2 }' file
01
26
49
71

或者您可以在sed中执行类似操作:

[jaypal:~/Temp] sed -n '/Series B/,/^$/s/\(.*[^ ]\) \(.*[^ ]\) \(.*\)/\2/p' file
01
26
49
71

答案 1 :(得分:1)

假设表格由空行分隔:

awk '$0 ~ p, !NF {
  if (!($0 ~ p) && NF) print $c
  }' p='Series B' c=2 infile

$0 ~ p, !NF - 用逗号分隔的一对模式指定一系列记录。 如果当前记录$ 0与指示的模式匹配,则第一个计算结果为true 变量p的值。当NF的值(字段数)时,第二个是真的 为0(空行或空行)。

if (!($0 ~ p) && NF) print $c - 如果当前记录与模式p不匹配 (即跳过标题),和(&&)当前记录包含至少一列(NF != 0) 打印所需的列。

答案 2 :(得分:0)

我更喜欢这种方式:

awk -v sect="$1" -v col="$2" '
/Series/ {header = $0; next}
NF > 1 {
    set[header] = set[header]$col"|";
}
END {print set[sect];}
' $3 | tr '|' '\n'

我介绍了关联数组和临时分隔符(如果你不需要对“系列”进行排序就不需要,只需使用“\ n”并省略tr),不要依赖空行,使用“|”作为临时sep,使用tr将其传回。

这是我的常见解决方案,因为在现实生活中我可以创建自定义“排序列”,然后通过管道进行unix排序,然后将其剪切回来。 Nawk(alas AIX)没有排序,unix排序比awk中的任何手工排序要好得多。