【问题标题】:AWK - replace specific column on matching line, then print other linesAWK - 替换匹配行上的特定列,然后打印其他行
【发布时间】:2016-11-08 02:29:46
【问题描述】:

我正在尝试更改数千行长的 DNA 序列“标题”行中的列/字段。具体来说,我想更改标题的第一个字段(compX_seqy),它总是以“>”开头:

前两个序列的示例:

 #cat example

 >comp0_seq1 444 [12:23]
 AGAGGACAC
 GATCCAACATA
 AGASCAC
 >comp0_seq2 333 [12:32:599:1]
 GTCGATC
 CYAACY
 CCCCA
 ...

我只想在第一列的末尾添加一个“A”,所有以“>”开头的行,

comp0_seq1A

然后打印该行的其余部分,然后打印下一行(序列),直到到达下一个“>”行(并重复)。

我希望输出看起来像这样:

>comp0_seq1A 444 [12:23]
AGAGGACAC
GATCCAACATA
AGASCAC
>comp0_seq2A 333 [12:32:599:1]
GTCGATC
CYAACY
CCCCA
...

我先尝试了这个:

awk '$1=$1"A"' example

>comp0_seq1A 444 [12:23]
AGAGGACACA
GATCCAACATAA
AGASCACA
>comp0_seq2A 333 [12:32:599:1]
GTCGATCA
CYAACYA
CCCCAA
A
A

它在所有行的第一个字段中添加了一个 A,所以不完全是。

然后我尝试了这个,使用正则表达式仅替换以“>”开头的行

# awk '/^>/ {print $1=$1"A";getline;print $0}' example
>comp0_seq1A
AGAGGACAC
>comp0_seq2A
GTCGATC

但这只会在匹配后打印第一行。那么,如何在匹配/替换之后打印所有/任何行,直到下一个“>”?我尝试使用“下一步”,但我想我不明白如何在这种情况下使用它。

有什么建议吗?我知道我很接近并且正在敲击键盘。

谢谢,LP。

【问题讨论】:

    标签: awk sed


    【解决方案1】:

    你几乎得到它。你只是用你的getline 想多了。

    awk 中,以下应该可以工作:

    $ awk '/^>/ {$1=$1"A"} 1' file.txt
    

    这通过在与正则表达式^> 匹配的所有行上运行大括号中的命令来工作。末尾的 1 是 awk 的简写,表示“打印当前行”。

    这样简单的替换的另一种选择是使用sed

    $ sed '/^>/s/ /A /' file.txt
    

    这是通过搜索匹配相同正则表达式的行,然后用字符串 (/A /) 替换第一个空格来实现的。 sed 默认会打印每一行,所以不需要显式打印。

    或者,如果您更喜欢替换第一个“字段”而不是第一个“字段分隔符”,这可以工作:

    $ sed 's/^\(>[^ ]*\)/\1A/' file.txt
    

    默认情况下,sed 正则表达式为“BRE”,因此需要对分组括号进行转义。 \1 是对搜索正则表达式中第一个(在本例中为“唯一”)括号表达式的引用。

    【讨论】:

    • 好答案。使用 sed,我会写 sed '/^>[^[:blank:]]\+/s//&A/' ,使用“空白”字符类,以防该文件中有选项卡。
    • 感谢所有选项。使用 sed/substitute 将空格替换为附加字符非常简单。
    • @glennjackman - 啊,很好的建议也使用&。我将按原样保留我的答案,因为它似乎适用于 OP 的数据,但感谢您的评论;毫无疑问,它会帮助其他可能有类似但不相同问题的人。
    猜你喜欢
    • 2019-03-28
    • 2018-02-26
    • 2011-06-20
    • 1970-01-01
    • 2011-07-20
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多