首页 > 解决方案 > 使用多个多字符分隔符时替换单个字段中的字符

问题描述

目标:我想在我的文件中将字符串“ ”和“ ”之间的每个“ -”实例替换为“”。.antisense::

我的文件的代表性样本:

>-::NC_009089.1:17609-17804(+)
ATTAAATAGAAAAAATGAATTTAATATAAAAAATTAAAGAAAATTCTAAAAAAAAAAAGATAAGGTCTTA
>antisense_tadA::NC_009089.1:19643-19848(-)
TTTATAAAAATATTTAGTGTTTTTTTTAAATTAGTTCTAAAATAATTTTTAGATATTCATACAAGAGTGT
>-::NC_009089.1:20139-20394(-)
GCTGTTTTTCTATATATGAATTTTGCTACTTTTACATTATTATTATTAAAATAATCTAATTTAAACTCAT
>antisense_recR::NC_009089.1:22931-23105(+)
TCATCTATAATCGCTTTAGATAAAGCTTCCACATCATTAGTATTCATATTAATAATATGAAAAGCCAATC
>antisense_16s_rRNA::NC_009089.1:25279-26010(-)
CTCTATTTTCCTTTTTATTCTATATTTAAATTTTTTATTTACAAGAATATTTTTAATATAACATATTATG
>antisense_tRNA-Leu_tRNA-Met::NC_009089.1:30389-30422(+)
TTTACATAGAGTTAACACTCTAAAAACTGCACA
>antisense_tRNA-Arg_tRNA-Gly_tRNA-Asp_tRNA-Val::NC_009089.1:30559-31181(-)
CTTAACTTCTGTGTTCGGAATGGGAACAGGTGTATCCTCTTTCCCACCAAGTACCATCAGCGCTAAAGAG

期望的输出:

>-::NC_009089.1:17609-17804(+)
ATTAAATAGAAAAAATGAATTTAATATAAAAAATTAAAGAAAATTCTAAAAAAAAAAAGATAAGGTCTTA
>antisense_tadA::NC_009089.1:19643-19848(-)
TTTATAAAAATATTTAGTGTTTTTTTTAAATTAGTTCTAAAATAATTTTTAGATATTCATACAAGAGTGT
>-::NC_009089.1:20139-20394(-)
GCTGTTTTTCTATATATGAATTTTGCTACTTTTACATTATTATTATTAAAATAATCTAATTTAAACTCAT
>antisense_recR::NC_009089.1:22931-23105(+)
TCATCTATAATCGCTTTAGATAAAGCTTCCACATCATTAGTATTCATATTAATAATATGAAAAGCCAATC
>antisense_16s_rRNA::NC_009089.1:25279-26010(-)
CTCTATTTTCCTTTTTATTCTATATTTAAATTTTTTATTTACAAGAATATTTTTAATATAACATATTATG
>antisense_tRNA.Leu_tRNA.Met::NC_009089.1:30389-30422(+)
TTTACATAGAGTTAACACTCTAAAAACTGCACA
>antisense_tRNA.Arg_tRNA.Gly_tRNA.Asp_tRNA.Val::NC_009089.1:30559-31181(-)
CTTAACTTCTGTGTTCGGAATGGGAACAGGTGTATCCTCTTTCCCACCAAGTACCATCAGCGCTAAAGAG

你会注意到上面所有的行都应该被打印到输出,但是这个例子中只有以“ >”开头的最后两行看起来不同(其中每个“ ”在字符串“ ”和“ ”之间-被替换为“ ”)。这是因为以“”开头的前五行在所描述的字段中没有包含“”的字符串。.antisense::>-

我一直在尝试使用awk来实现这一点,但如果它们更容易,我也愿意接受 sed 解决方案。我的一般方法是使用字符串“ antisense”或“ antisense_”作为一个分隔符,使用“ :”或“ ::”作为另一个分隔符,从而使第 2 ( $2) 列成为字符替换的目标字段。

以下是我的一些尝试及其错误输出

$ awk -F'>antisense_|:' '/^ *>antisense_/ {gsub("-", ".", $2); print}' file
    >antisense_tadA::NC_009089.1:19643-19848(-)
    >antisense_recR::NC_009089.1:22931-23105(+)
    >antisense_16s_rRNA::NC_009089.1:25279-26010(-)
     tRNA.Leu_tRNA.Met  NC_009089.1 30389-30422(+)
     tRNA.Arg_tRNA.Gly_tRNA.Asp_tRNA.Val  NC_009089.1 30559-31181(-)

$ awk 'BEGIN {OFS=FS="/antisense/|:"} {gsub("-", ".", $2)} 1' file
    >-::NC_009089.1:17609-17804(+)
    ATTAAATAGAAAAAATGAATTTAATATAAAAAATTAAAGAAAATTCTAAAAAAAAAAAGATAAGGTCTTA
    >antisense_tadA::NC_009089.1:19643-19848(-)
    TTTATAAAAATATTTAGTGTTTTTTTTAAATTAGTTCTAAAATAATTTTTAGATATTCATACAAGAGTGT
    >-::NC_009089.1:20139-20394(-)
    GCTGTTTTTCTATATATGAATTTTGCTACTTTTACATTATTATTATTAAAATAATCTAATTTAAACTCAT
    >antisense_recR::NC_009089.1:22931-23105(+)
    TCATCTATAATCGCTTTAGATAAAGCTTCCACATCATTAGTATTCATATTAATAATATGAAAAGCCAATC
    >antisense_16s_rRNA::NC_009089.1:25279-26010(-)
    CTCTATTTTCCTTTTTATTCTATATTTAAATTTTTTATTTACAAGAATATTTTTAATATAACATATTATG
    >antisense_tRNA-Leu_tRNA-Met::NC_009089.1:30389-30422(+)
    TTTACATAGAGTTAACACTCTAAAAACTGCACA
    >antisense_tRNA-Arg_tRNA-Gly_tRNA-Asp_tRNA-Val::NC_009089.1:30559-31181(-)
    CTTAACTTCTGTGTTCGGAATGGGAACAGGTGTATCCTCTTTCCCACCAAGTACCATCAGCGCTAAAGAG

$ awk 'BEGIN {OFS=FS="antisense|:"} {gsub("-", ".", $2)} 1' file
    >-::NC_009089.1:17609-17804(+)
    ATTAAATAGAAAAAATGAATTTAATATAAAAAATTAAAGAAAATTCTAAAAAAAAAAAGATAAGGTCTTA
    >antisense_tadA::NC_009089.1:19643-19848(-)
    TTTATAAAAATATTTAGTGTTTTTTTTAAATTAGTTCTAAAATAATTTTTAGATATTCATACAAGAGTGT
    >-::NC_009089.1:20139-20394(-)
    GCTGTTTTTCTATATATGAATTTTGCTACTTTTACATTATTATTATTAAAATAATCTAATTTAAACTCAT
    >antisense_recR::NC_009089.1:22931-23105(+)
    TCATCTATAATCGCTTTAGATAAAGCTTCCACATCATTAGTATTCATATTAATAATATGAAAAGCCAATC
    >antisense_16s_rRNA::NC_009089.1:25279-26010(-)
    CTCTATTTTCCTTTTTATTCTATATTTAAATTTTTTATTTACAAGAATATTTTTAATATAACATATTATG
    >antisense|:_tRNA.Leu_tRNA.Metantisense|:antisense|:NC_009089.1antisense|:30389-30422(+)
    TTTACATAGAGTTAACACTCTAAAAACTGCACA
    >antisense|:_tRNA.Arg_tRNA.Gly_tRNA.Asp_tRNA.Valantisense|:antisense|:NC_009089.1antisense|:30559-31181(-)
    CTTAACTTCTGTGTTCGGAATGGGAACAGGTGTATCCTCTTTCCCACCAAGTACCATCAGCGCTAAAGAG

我了解我的每次尝试为何/如何失败,但我不确定如何使用 awk 正确指定多个多字符分隔符,同时确保定义的分隔符在输入和输出文件之间保持不变(无替换)。有什么想法或建议吗?

标签: awksed

解决方案


对于显示的示例数据,此 awk 应该适合您:

awk 'match($0, /antisense.*::/) {s = substr($0, RSTART, RLENGTH); 
gsub(/-/, ".", s); $0 = substr($0, 1, RSTART-1) s substr($0, RSTART + RLENGTH)} 1' file

>-::NC_009089.1:17609-17804(+)
ATTAAATAGAAAAAATGAATTTAATATAAAAAATTAAAGAAAATTCTAAAAAAAAAAAGATAAGGTCTTA
>antisense_tadA::NC_009089.1:19643-19848(-)
TTTATAAAAATATTTAGTGTTTTTTTTAAATTAGTTCTAAAATAATTTTTAGATATTCATACAAGAGTGT
>-::NC_009089.1:20139-20394(-)
GCTGTTTTTCTATATATGAATTTTGCTACTTTTACATTATTATTATTAAAATAATCTAATTTAAACTCAT
>antisense_recR::NC_009089.1:22931-23105(+)
TCATCTATAATCGCTTTAGATAAAGCTTCCACATCATTAGTATTCATATTAATAATATGAAAAGCCAATC
>antisense_16s_rRNA::NC_009089.1:25279-26010(-)
CTCTATTTTCCTTTTTATTCTATATTTAAATTTTTTATTTACAAGAATATTTTTAATATAACATATTATG
>antisense_tRNA.Leu_tRNA.Met::NC_009089.1:30389-30422(+)
TTTACATAGAGTTAACACTCTAAAAACTGCACA
>antisense_tRNA.Arg_tRNA.Gly_tRNA.Asp_tRNA.Val::NC_009089.1:30559-31181(-)
CTTAACTTCTGTGTTCGGAATGGGAACAGGTGTATCCTCTTTCCCACCAAGTACCATCAGCGCTAAAGAG

推荐阅读