[英]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
我找不到使用變量代號的解決方案; 我嘗試使用:
在第一種情況下,我不知道 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.