You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用sed保留制表符分隔文件中的GO:#######字符串及指定空行

解决制表符分隔文件中保留GO格式字符串的sed问题

问题背景

有一个大型制表符分隔文件,需要保留每行中任意数量的GO:#######格式字符串,以及仅包含英文句点的行。使用原有sed命令时,因正则贪婪匹配导致误删中间有效内容,无法得到期望结果。

原有命令

sed -r 's/	`.+`	//g' file1.txt > file2.txt

现有内容

GO:1234567    `text1`moretext`    GO:5373845    `diff`text`     GO:5438534     `text`text
.
GO:3333333     `txt`text`    GO:5553535    `misc`text
.
.

期望结果

GO:1234567    GO:5373845    GO:5438534
.
GO:3333333    GO:5553535
.
.

实际错误结果

GO:1234567    GO:5438534     `text`text
.
GO:3333333    GO:5553535    `misc`text
.
.

问题原因

原有命令中的.+是贪婪匹配,会从第一个开始匹配到距离最远的下一个,跳过中间的GO字段;同时仅匹配前后带制表符的...内容,导致行尾无制表符的非GO内容无法被清理。

解决方案

方法1:使用sed精准匹配清理非GO内容

通过正则精准定位并删除所有非GO格式的字段,同时保留句点行:

sed -E '
    /^\.$/!{
        s/([^	]*GO:[0-9]{7}[^	]*)/\1\n/g;
        s/[^\n]*\n//g;
        s/\n/	/g;
        s/^	|	$//g
    }
' file1.txt > file2.txt

命令解释:

  1. /^\.$/!:仅对非句点行执行操作
  2. s/([^ ]*GO:[0-9]{7}[^ ]*)/\1\n/g:将每个GO格式字段和其前后的制表符替换为“GO字段+换行符”,把GO字段单独拆分到每行
  3. s/[^\n]*\n//g:删除所有不包含换行符的内容(即非GO字段),只留下GO字段的行
  4. s/\n/ /g:将换行符替换为制表符,把GO字段重新用制表符分隔
  5. s/^ | $//g:删除行首和行尾多余的制表符

方法2:用awk更高效处理字段(推荐)

awk天生擅长处理分隔符字段,逻辑更清晰,适合大型文件:

awk -F'	' '
    /^\.$/ {print; next}
    {
        line = ""
        for (i=1; i<=NF; i++) {
            if ($i ~ /^GO:[0-9]{7}$/) {
                line = line (line ? "	" : "") $i
            }
        }
        print line
    }
' file1.txt > file2.txt

命令解释:

  1. -F' ':指定制表符为字段分隔符
  2. /^\.$/ {print; next}:如果是仅含句点的行,直接打印并跳过后续处理
  3. 遍历每行的所有字段,仅保留匹配GO:#######格式的字段
  4. 将保留的字段用制表符连接后打印

内容的提问来源于stack exchange,提问作者timtimbruno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:20:38