AWK - 如何有选择地修改txt文件

时间:2012-12-13 17:04:09

标签: awk

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

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 /之间(显示这些记录不变)只显示第二个字段,匹配regex / husky /
  3. 我希望这很有用......

3 个答案:

答案 0 :(得分:5)

此:

awk '/regex2/,/regex3/'

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

简单版本的恕我直言不应该被使用,因为它的简洁性并不值得当你尝试用其他标准建立它时引入的困难,例如:不打印起始线和/或不打印终点线和/或引入其他RE以在您现在的范围内匹配。

鉴于此,您将从这个脚本开始:

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

并且你只想打印你发现“哈士奇”的行,所以这是简单明了的调整:

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”。

答案 1 :(得分:1)

infile中:

$ 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

答案 2 :(得分:0)

您的问题存在一些含糊之处,但应该这样做:

awk '/regex2/ {inside=1}
     /regex3/ {inside=0}
     $2 ~ /regex1/ && inside {print $2}
     !inside {print}' input_file