字符串函数文档:https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html
带子:
如果特殊字符“&”出现在替换中,它代表正则表达式匹配的精确子字符串。
awk '
$2 == 9790725{
if ($0 ~ /\;accepted=/){
sub(/accepted=[^;]*/,"&,entryX")
}
else{
sub(/$/,";accepted=entryX;")
}
}1' file
结果:
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;ccds_transcript=true;clingen=0;accepted=entryX;
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;accepted=entry0,entry1,entryX;ccds_transcript=true;clingen=1
请注意,您也可以使用具有 GNU awk 和 gensub 功能的组。这里不需要,但它可以用于更复杂的替换。
gensub() 提供了 sub() 中没有的附加功能
或 gsub():在
替换文本。这是通过在正则表达式中使用括号来完成的
标记组件,然后在替换文本中指定“\N”,
其中 N 是从 1 到 9 的数字。
回答您的评论:
假设你有这个输入:
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;ccds_transcript=true;clingen=0
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;accepted=entry0,entry1;ccds_transcript=true;clingen=1
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;accepted=entry0,entry1;ccds_transcript=true;clingen=1;rejected=entry2
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;accepted=entry0,entry1,entry2;ccds_transcript=true;clingen=1
你想添加 entry2 :
- 第一行没有接受字段
- 第三个拒绝进入2
- 第四个已经有 entry2。
我调整了我的脚本来处理这些行:
awk -v entry="entry2" '
($2 == 9790725) && \
!($0 ~ "accepted=[^;]*" entry) && \
!($0 ~ "rejected=[^;]*" entry){
if ($0 ~ /\;accepted=/){
sub(/accepted=[^;]*/,"&," entry)
}
else{
sub(/$/,";accepted=" entry ";")
}
}1' file
现在,awk 将在追加之前检查条目是否已被接受或拒绝。如果您想要不同的行为,请删除这些条件之一。
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;ccds_transcript=true;clingen=0;accepted=entry2;
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;accepted=entry0,entry1,entry2;ccds_transcript=true;clingen=1
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;accepted=entry0,entry1;ccds_transcript=true;clingen=1;rejected=entry2
1 9790725 . TTCCTCC T . . ACMG=US;benign_cv=0;accepted=entry0,entry1,entry2;ccds_transcript=true;clingen=1
我认为文件的结构没有经过调整(它看起来像一个 csv,具有多个字段分隔符和有时不存在或以不同顺序排列的列)。使用json 类型的结构和适应工具来读取/更新它会更容易(不是awk)。
您还可以使用split 函数在 awk 中处理此文件(并在 =、;、, 上拆分)。我懒得尝试,希望有更好的文件结构。