如何移除TSV文件指定列中末尾的_0或_1后缀?
解决TSV文件中ID后缀误删问题
你当前的awk命令错误在于正则表达式/_[0-9]+$/——它会匹配任意末尾的下划线加数字序列,包括i_224里的_224,所以才会把i_224变成i。你的需求是仅移除末尾的_0或_1后缀,保留第一个下划线后的数字ID,下面是两种精准的解决方法:
方案一:精准匹配末尾的_0/_1
直接修改正则表达式,只匹配字符串末尾的_0或_1,替换为空即可:
awk -F'\t' -v OFS='\t' '{ if ($0 ~ /^#/) { print next } # 仅移除末尾的_0或_1后缀 gsub(/_[01]$/, "", $3) gsub(/_[01]$/, "", $14) print }' "$input_file" > "$output_file"
说明:
/_[01]$/仅匹配末尾的_0或_1,不会影响i_224这类末尾是多位数的ID。- 保留了原脚本中跳过注释行(以
#开头)的逻辑,符合TSV文件的常见注释格式。
方案二:按ID结构拆分拼接(更直观)
如果ID的固定格式是前缀_数字或前缀_数字_0/1,可以通过拆分ID的方式精准保留前两部分:
awk -F'\t' -v OFS='\t' '{ if ($0 ~ /^#/) { print next } # 定义清理ID的函数 function clean_id(id) { split(id, parts, "_") # 如果ID有3个部分且最后部分是0/1,则返回前两部分拼接结果 if (length(parts) == 3 && (parts[3] == "0" || parts[3] == "1")) { return parts[1] "_" parts[2] } # 否则返回原ID return id } $3 = clean_id($3) $14 = clean_id($14) print }' "$input_file" > "$output_file"
说明:
- 用
split函数把ID按下划线拆分成数组,通过判断数组长度和最后一个元素的值来决定是否修改ID。 - 这种方法逻辑更清晰,后续如果ID格式有小变化(比如允许
_2后缀但不需要处理),修改条件即可。
内容的提问来源于stack exchange,提问作者eesiribloom
相关产品推荐
相关产品推荐

