Bash下提取多字段并生成带条件列的CSV文件
解析ID生成三列CSV的AWK解决方案
需求
解析ID字符串生成三列CSV,规则如下:
- 第一列:提取
tr|XXXX|格式中两个竖线之间的字段 - 第三列:提取第二个竖线之后、
OS=之前的所有内容 - 第二列(条件字段):
- 行内存在
GN=XXX时,提取XXX(GN=后到下一个空格前的内容) - 无
GN=时,提取第三列第一个空格前的内容
- 行内存在
输入示例
tr|I1WXP1|I1WXP1_9EURY Methyl coenzyme M reductase subunit A (Fragment) OS=uncultured euryarchaeote OX=114243 GN=mcrA PE=4 SV=1
tr|A0A059VAR9|A0A059VAR9_9EURY V-type ATP synthase beta chain (Fragment) OS=Halorubrum sp. Ga66 OX=1480727 GN=atpB PE=3 SV=1
tr|Q51760|Q51760_9EURY Glutaredoxin-like protein OS=Pyrococcus furiosus OX=2261 PE=1 SV=1
期望输出
I1WXP1,mcrA,I1WXP1_9EURY Methyl coenzyme M reductase subunit A (Fragment) A0A059VAR9,atpB,A0A059VAR9_9EURY V-type ATP synthase beta chain (Fragment) Q51760,Q51760_9EURY,Q51760_9EURY Glutaredoxin-like protein
AWK解决方案
awk '{ # 保存原始行用于后续GN匹配 original = $0; # 提取第一列:tr|XXXX|中的XXXX split(original, parts, "|"); col1 = parts[2]; # 提取第三列:第二个|之后到OS=之前的内容 temp = original; sub(/^.*\|/, "", temp); # 删除开头到第二个|的部分 sub(/ OS=.*/, "", temp); # 删除OS=及之后的部分 col3 = temp; # 处理第二列的条件逻辑 if (match(original, /GN=([^ ]+)/)) { col2 = substr(original, RSTART + 3, RLENGTH - 3); } else { split(col3, c3_parts, " "); col2 = c3_parts[1]; } # 输出三列CSV格式 print col1 "," col2 "," col3; }' input.txt
代码说明
- 第一列提取:通过
split按竖线分割原始行,直接取分割后的第二个元素。 - 第三列提取:复制原始行到临时变量,两次使用
sub删除无关内容,保留目标片段。 - 第二列条件处理:
- 用
match匹配GN=XXX模式,通过substr截取GN=后的内容。 - 未匹配到
GN=时,将第三列按空格分割,取第一个元素。
- 用
- 输出格式:三列用逗号连接,符合CSV要求。
内容的提问来源于stack exchange,提问作者StephenAvery84
相关产品推荐
相关产品推荐

