删除除第一个单词以外的以特殊字符开头的整行

use*_*245 4 sed

我最近开始使用 linux 并且我几乎完全忘记了 sed 命令。我需要编辑一个包含一堆以公共字符“>”开头的长行的文件,并删除该行的其余部分,只保留第一个单词,但不要使用 sed 命令触及任何不以“>”开头的行。

换句话说,我需要转这个(为了演示目的,只是第一个条目的一部分):

>YAL001C TFC3 SGDID:S000000001, Chr I from 151006-147594,151166-151097, Genome Release 64-1-1, reverse complement, Verified ORF, "Largest of six subunits of the RNA polymerase III transcription initiation factor complex (TFIIIC); part of the TauB domain of TFIIIC that binds DNA at the BoxB promoter sites of tRNA and similar genes; cooperates with Tfc6p in DNA binding"
MVLTIYPDELVQIVSDKIASNKGKITLNQLWDISGKYFDLSDKKVKQFVLSCVILKKDIE
VYCDGAIP*
Run Code Online (Sandbox Code Playgroud)

进入这个:

>YAL001C
MVLTIYPDELVQIVSDKIASNKGKITLNQLWDISGKYFDLSDKKVKQFVLSCVILKKDIE
VYCDGAIP*
Run Code Online (Sandbox Code Playgroud)

Joh*_*024 8

我在这里介绍了四种解决方案,两种使用sed,一种使用awk,一种使用perl。开始:

$ sed -r 's/^(>[^ ]+) .*/\1/' inputfile
Run Code Online (Sandbox Code Playgroud)

在您的示例输入上,这会产生输出:

>YAL001C
LTIYPDELVQIVSDKIASNKGKITLNQLWDISGKYFDLSDKKVKQFVLSCVILKKDIE
VYCDGAIP*
Run Code Online (Sandbox Code Playgroud)

该代码使用 sed 的替代命令s。替代命令的形式为s/old/new/。在这种情况下,“旧”部分由以下部分组成:

  • ^

    这是一行开始的 sed-speak。

  • (>[^ ]+)

    这是指由尖括号后跟一个或多个非空白字符组成的一组字符。因为这是在括号中,我们稍后可以将其称为\1.

  • .*

    这是指一个空格后跟任意数量的任意字符。

当替换命令完成时,任何这样的一行的整个都被替换为>紧随其后的和非空白字符。

任何不以该组合开头的行都将不变地发送到输出。

替代解决方案

在评论中,steeldriver 提出了另一种方法:

sed '/^>/ s/\s.*//'
Run Code Online (Sandbox Code Playgroud)

在此解决方案中,替换命令前面是修饰符/^>/,该修饰符限制替换命令仅在以 开头的行上运行>。知道该行以尖括号开头,那么只需删除第一个空格和第一个空格后面的所有内容。这就是命令的s/\s.*//作用。

所有其他线路不变地通过。

使用替代解决方案 awk

awk '/^>/ {print $1;next} 1' inputfile
Run Code Online (Sandbox Code Playgroud)

awk脚本由两个表达式组成:

  • /^>/ {print $1;next}

    awk支持与sed. 因此,初始表达式将此命令限制为仅对以 开头的行进行操作>。对于这些行,打印第一个字段。 next告诉awk跳到下一行并重新开始。

  • 1

    1is 是awk打印整行的神秘简写。这仅在next未执行前面表达式中的awk命令的行上执行,这意味着仅当该行不以>.

使用替代解决方案 perl

Steeldriver 还建议:

perl -anle 'print $F[0] if /^>/ || $_'
Run Code Online (Sandbox Code Playgroud)

这四个选项的含义如下:

  • -n告诉perl隐式循环输入行

  • -a告诉 perl 打开自动拆分,创建@F数组

  • -l 启用自动行尾处理

  • -e 告诉它运行下面的命令,消除对 perl 脚本文件的需要。

perl 命令本身是相当可读的:

print $F[0] if /^>/ || $_
Run Code Online (Sandbox Code Playgroud)

如果该行以>. 否则,它将打印整行。