簡體   English   中英

AWK:動態改變FS或RS

[英]AWK: dynamically change FS or 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
}
)

關鍵是:

  • 當代碼塊{...}前面沒有autoX (X 可以是 1,2,3 等)時,不會發生任何變化。
  • autoX后跟代碼塊{...}時,應該會發生更改。
  • 代碼塊和autoX的值通過添加\\\\good//moderate ,需要從{...}本身讀取。
  • 整行應該從{...}刪除,如果它包含短語remove

提示:它可能是可以使用這里解釋的想法的東西,這個特定的例子

目前,我只能通過以下代碼滿足最后一個要求:

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

預先感謝您的技能和時間,用解決這個問題。

這是我解決這個問題的嘗試:

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.

您可以使用兩個換行符作為記錄分隔符並處理每個可能包含一個的記錄

autoX
{
  ...
  ...
}

堵塞。

awk '
BEGIN{
  RS="\n\n"                          # set record separator RS to two newlines
  a["good"]; a["moderate"]           # create array a with indices "good" and "moderate"
}                                    
{                                    
  sub(/\n[ \t]+remove[^;]+;/, "")    # remove line containing "remove xxx;"
  for (i in a){                      # loop array indices "good" and "moderate"
    if (index($0, i)){               # if value exists in record
      sub(i";", i";//"i)             # add "//good" to "good;" or "//moderate" to "moderate;"
      match($0, /(auto[0-9]+)/)      # get pos. RSTART and length RLENGTH of "autoX"
      if (RSTART){                   # RSTART > 0 ?
                                     # set prefix including "autox", "//value" and suffix
        $0=substr($0, 1, RSTART+RLENGTH-1) "//"i substr($0, RSTART+RLENGTH)
      }
      break                          # stop looping (we already replaced "autoX")
    }
  }
  printf "%s", (FNR==1 ? "" : RS)$0  # print modified line prefixed by RS if not the first line
}
' Input_file

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM