首页 > 解决方案 > AWK:动态改变FS或RS

问题描述

我似乎无法获得动态交换FS/RS变量的技巧,因此我从输入中得到以下结果:

输入文件

header 1
header 2
{
something should not be removed
}

50

( 
auto1
{
    type        good;
    remove      not useful;
}

 auto2
{
    type        good;
    keep        useful;
}

 auto3
{
    type        moderate;
    remove      not useful;
}
)

输出文件

header 1
header 2
{
something that should not be removed
}

50

( 
auto1//good
{
    type        good;//good
}

auto2//good
{
    type        good;//good
    keep        useful;
}

auto3//moderate
{
    type        moderate;//moderate
}
)

关键是:

提示:这可能是可以使用这里解释的想法的东西,这个特定的例子

目前,我只能满足最后一个要求,代码如下:

awk ' {$1=="{"; FS=="}";} {$1!="}"; gsub("remove",""); print NR"\t\t"$0}' Input_file

提前感谢您的技能和时间,用解决这个问题。

标签: regexawkenvironment-variablestext-manipulation

解决方案


这是我解决此问题的尝试:

awk '
FNR==NR{
  if($0~/auto[0-9]+/){
    found1=1
    val=$0
    next
  }
  if(found1 && $0 ~ /{/){
    found2=1
    next
  }
  if(found1 && found2 && $0 ~ /type/){
    sub(/;/,"",$NF)
    a[val]=$NF
    next
  }
  if($0 ~ /}/){
    found1=found2=val=""
  }
  next
}
found3 && /not useful/{
  next
}
/}/{
  found3=val1=""
}
found3 && /type/{
  sub($NF,$NF"//"a[val1])
}
/auto[0-9]+/ && $0 in a{
  print $0"//"a[$0]
  found3=1
  val1=$0
  next
}
1
'  Input_file  Input_file


说明:在此处添加上述代码的详细说明。

awk '                                      ##Starting awk program from here.
FNR==NR{                                   ##FNR==NR will be TRUE when first time Input_file is being read.
  if($0~/auto[0-9]+/){                     ##Check condition if a line is having auto string followed by digits then do following.
    found1=1                               ##Setting found1 to 1 which makes sure that the line with auto is FOUND to later logic.
    val=$0                                 ##Storing current line value to variable val here.
    next                                   ##next will skip all further statements from here.
  }
  if(found1 && $0 ~ /{/){                  ##Checking condition if found1 is SET and line has { in it then do following.
    found2=1                               ##Setting found2 value as 1 which tells program further that after auto { is also found now.
    next                                   ##next will skip all further statements from here.
  }
  if(found1 && found2 && $0 ~ /type/){     ##Checking condition if found1 and found2 are ET AND line has type in it then do following.
    sub(/;/,"",$NF)                        ##Substituting semi colon in last field with NULL.
    a[val]=$NF                             ##creating array a with variable var and its value is last column of current line.
    next                                   ##next will skip all further statements from here.
  }
  if($0 ~ /}/){                            ##Checking if line has } in it then do following, which basically means previous block is getting closed here.
    found1=found2=val=""                   ##Nullify all variables value found1, found2 and val here.
  }
  next                                     ##next will skip all further statements from here.
}
/}/{                                       ##Statements from here will be executed when 2nd time Input_file is being read, checking if line has } here.
  found3=val1=""                           ##Nullifying found3 and val1 variables here.
}
found3 && /type/{                          ##Checking if found3 is SET and line has type keyword in it then do following.
  sub($NF,$NF"//"a[val1])                  ##Substituting last field value with last field and array a value with index val1 here.
}
/auto[0-9]+/ && $0 in a{                   ##Searching string auto with digits and checking if current line is present in array a then do following.
  print $0"//"a[$0]                        ##Printing current line // and value of array a with index $0.
  found3=1                                 ##Setting found3 value to 1 here.
  val1=$0                                  ##Setting current line value to val1 here.
  next                                     ##next will skip all further statements from here.
}
1                                          ##1 will print all edited/non0-edited lines here.
'  Input_file  Input_file                  ##Mentioning Input_file names here.

推荐阅读