3

我想打印每条记录的特定第二个字段(匹配正则表达式)

awk '$2 ~ /regex1/'

但是,只有在 regex2 和 regex3 之间的特定记录

awk '/regex2/,/regex3/'

其他不在 regex2 和 regex3 之间的记录应正常打印(所有字段)

任何想法,如何把它放在一起?

输入和输出的快速示例:

输入

parrot   milana  3 ukraine
dog      husky   1 poland
cat      husky   5 france
elephant malamut 5 belgium
bird     husky   5 turkey

输出:(给我看

parrot   milana  3 ukraine
dog      husky   1 poland
         husky            
elephant malamut 5 belgium    
bird     husky   5 turkey
  1. 显示整个输入但是:
  2. 在 /dog/ 和 /elephant/ 之间(显示这些记录不变)只显示第二个字段,它匹配正则表达式 /husky/

我希望这是有用的...

4

3 回答 3

5

这个:

awk '/regex2/,/regex3/'

是简写

awk '/regex2/{f=1} f; /regex3/{f=0}'

恕我直言不应该使用速记版本,因为当您尝试使用其他标准构建它时,它的简洁不值得它引入的困难,例如不打印起始线和/或不打印结束线和/或引入其他 RE像你现在所做的那样在范围内匹配。

鉴于此,您将从以下脚本开始:

awk '/dog/{f=1} f; /elephant/{f=0}'

并且您只想打印找到“husky”的行,因此这是简单而明显的调整:

awk '/dog/{f=1} f && /husky/; /elephant/{f=0}'

编辑:响应更改的要求,并使用制表符分隔的文件:

$ cat file
parrot  milana  3       ukraine
dog     husky   1       poland
cat     husky   5       france
elephant        malamut 5       belgium
bird    husky   5       turkey

$ awk '
BEGIN{ FS=OFS="\t" }
/elephant/ {f=0}
{
   if (f) {
      if ($2 == "husky") {
         print "", $2
      }
   }
   else {
      print
   }
}
/dog/      {f=1}
' file
parrot  milana  3       ukraine
dog     husky   1       poland
        husky
elephant        malamut 5       belgium
bird    husky   5       turkey

你可以写得更简洁:

$ awk '
BEGIN{ FS=OFS="\t" }
/elephant/ {f=0}
f && /husky/ { print "", $2 }
!f
/dog/      {f=1}
' file
parrot  milana  3       ukraine
dog     husky   1       poland
        husky
elephant        malamut 5       belgium
bird    husky   5       turkey

但我认为 if-else 语法对于 awk 的新手来说是最清晰和最容易修改的。如果您想要不同的输出格式,请在手册中查找“printf”。

于 2012-12-13T17:57:23.307 回答
1

文件:

$ cat input

parrot   milana  3 ukraine
dog      husky   1 poland
cat      husky   5 france
elephant malamut 5 belgium
bird     husky   5 turkey

命令:

$ awk '/dog/{m=1} $2 ~ /husky/ && m{print $2} !m{print} /elephant/{m=0}' input

parrot   milana  3 ukraine
husky
husky
bird     husky   5 turkey
于 2012-12-13T19:08:06.840 回答
0

您的问题有些含糊不清,但应该这样做:

awk '/regex2/ {inside=1}
     /regex3/ {inside=0}
     $2 ~ /regex1/ && inside {print $2}
     !inside {print}' input_file
于 2012-12-13T17:09:44.750 回答