簡體   English   中英

當其中一個與 awk 匹配正則表達式模式時刪除分隔的行塊

[英]Removing a delimited block of lines when one of them matches a regex pattern with awk

讓我們假設以下 reprepro 分發文件:

Origin: git.sdxlive.com/git/PPA
Label: Ubuntu focal
Suite: focal
Version: 20.04
Codename: focal
Architectures: i386 amd64
Components: stable unstable
Limit: 0
Description: Latest Ubuntu focal 20.04 packages
Contents: .gz .bz2
Tracking: keep
SignWith: xxxxxxxxxxxxxxxxxxxx
Signed-By: xxxxxxxxxxxxxxxxxxxx
ValidFor: 2y 6m
Log: packages.Ubuntu.log

Origin: git.sdxlive.com/git/PPA
Label: Ubuntu groovy
Suite: groovy
Version: 20.10
Codename: groovy
Architectures: i386 amd64
Components: stable unstable
Limit: 0
Description: Latest Ubuntu groovy 20.10 packages
Contents: .gz .bz2
Tracking: keep
SignWith: xxxxxxxxxxxxxxxxxxxx
Signed-By: xxxxxxxxxxxxxxxxxxxx
ValidFor: 2y 6m
Log: packages.Ubuntu.log

目標是刪除由 'Origin:' 分隔的整個行塊,當它包含行 "Codename: ${os_code_name}" 時刪除一個空行,其中 os_code_name 是一個 bash 變量。

所以預期的輸出是:

Origin: git.sdxlive.com/git/PPA
Label: Ubuntu groovy
Suite: groovy
Version: 20.10
Codename: groovy
Architectures: i386 amd64
Components: stable unstable
Limit: 0
Description: Latest Ubuntu groovy 20.10 packages
Contents: .gz .bz2
Tracking: keep
SignWith: xxxxxxxxxxxxxxxxxxxx
Signed-By: xxxxxxxxxxxxxxxxxxxx
ValidFor: 2y 6m
Log: packages.Ubuntu.log

如果沒有變量代號,我們可以使用例如以下內容來刪除與焦點代號匹配的塊:

awk '/^Origin: /{s=x} {s=s $0 RS} /^$/{if(s!~/Codename: focal/) printf "%s",s}' distributions

我找不到使用變量代號的解決方案; 我嘗試使用:

  1. --assign=var="${os_code_name}"
  2. 環境["os_code_name"]

在第一種情況下,我不知道 awk 如何區分字符串 'Codename:' 和變量 var,因為我們不能使用“$var”。 以下顯然不起作用:

awk --assign=var="${os_code_name}" '/^Origin: /{s=x} {s=s $0 RS} /^$/{if(s!~/Codename: $var/) printf "%s",s}' distributions

第二種情況,同樣不成功:

awk '/^Origin: /{s=x} {s=s $0 RS} /^$/{if(s!~/Codename: ENVIRON["os_code_name"]/) printf "%s",s}' distributions

我也檢查了這個答案

有什么建議嗎?

您能否嘗試使用顯示的示例進行跟蹤、編寫和測試,並且應該可以在所有類型的awk

os_code_name="focal" ##shell variable
awk -v co="$os_code_name" '
/Origin/{
  if(!foundCo && FNR>1){ print val }
  val=foundCo=""
}
/^Codename/ && $NF==co{
  foundCo=1
}
{
  val=(val?val ORS:"")$0
}
END{
  if(!foundCo){ print val }
}
'  Input_file

說明:為以上添加詳細說明。

os_code_name="focal"                     ##This is a shell variable.
awk -v co="$os_code_name" '              ##Starting awk program from here and setting co variable as value of os_code_name here.
/Origin/{                                ##Checking condition if line has Origin string in it then do following.
  if(!foundCo && FNR>1){ print val }     ##Checking condition if foundCo is NULL and FNR>1 then print val here.
  val=foundCo=""                         ##Nullifying variables here.
}
/^Codename/ && $NF==co{                  ##Checking condition if line starts with Codenam and last field is equal to variable.
  foundCo=1                              ##Setting value for foundCo here.
}
{
  val=(val?val ORS:"")$0                 ##Creating val which has all lines values from Origin to just before next occurrence of Origin it either gets printed above or gets NULL.
}
END{                                     ##Starting END block of this awk program from here.
  if(!foundCo){ print val }              ##Checking condition if foundCo is NULL then print val here.
}
'  Input_file                            ##Mentioning Input_file name here.

您可以使用空RS ,這是段落模式,並且不要在該代號存在的地方打印任何記錄。

awk -v cn="$cn" -v RS="" '!($0 ~ "Codename: " cn){print $0,"\n"}' file

該變量必須按照您鏈接的答案所說的方式傳遞。 模式匹配可以使用~ /.../~ "..." ,使用雙引號是你在這里必須做的, "Codename: " var是匹配的字符串。

暫無
暫無

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

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