Удалить всю строку, начиная со специального символа, кроме первого слова

Я совсем недавно начал использовать 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*

в это:

>YAL001C
MVLTIYPDELVQIVSDKIASNKGKITLNQLWDISGKYFDLSDKKVKQFVLSCVILKKDIE
VYCDGAIP*
4
задан 4 July 2014 в 01:00

1 ответ

Я представляю здесь четыре решения, два использования sed, одно использование awk, и одно использование perl. Запускаться:

$ sed -r 's/^(>[^ ]+) .*/\1/' inputfile

На Вашем демонстрационном входе это производит вывод:

>YAL001C
LTIYPDELVQIVSDKIASNKGKITLNQLWDISGKYFDLSDKKVKQFVLSCVILKKDIE
VYCDGAIP*

Код использует команду замены sed s. Команда замены находится в форме s/old/new/. В этом случае "старая" часть состоит из этих частей:

  • ^

    Это, sed-выступают за запуск строки.

  • (>[^ ]+)

    Это относится к группе символов, состоящих из угловой скобки, сопровождаемой одним или несколькими несимволами пробела. Поскольку это находится в круглой скобке, мы сможем обратиться к ней позже как \1.

  • .*

    Это относится к пробелу, сопровождаемому любым количеством любых символов.

Когда команда замены сделана, вся любая такая строка заменяется просто > и несимволы пробела, которые сразу следуют за ним.

Любые строки, не запускающиеся с той комбинации, отправляются в неизменный вывод.

Альтернативное решение

В комментариях steeldriver предлагает альтернативный подход:

sed '/^>/ s/\s.*//'

В этом решении команде замены предшествует модификатор /^>/ который ограничивает команду замены для работы только на строки, которые запускаются с >. Знание, что строка запускается с угловой скобки, затем только необходимо удалить первый пробел и все, что следует за первым пробелом. Это что команда s/\s.*// делает.

Через все другие строки проходят неизменные.

Использование альтернативного решения awk

awk '/^>/ {print $1;next} 1' inputfile

Это awk сценарий состоит к двум выражениям:

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

    awk поддерживает тот же стиль модификаторов как sed. Начальное выражение, таким образом, ограничивает эту команду для работы только на строки, которые запускаются с >. Для тех строк печатается первое поле. next говорит awk пропускать к следующей строке и запускаться.

  • 1

    1 awkзагадочное сокращение от печати целая строка. Это выполняется только на строках для который next команда в предыдущем выражении не выполняется, означая это awk достигает этой команды, только если строка не запускается с >.

Использование альтернативного решения perl

steeldriver также предлагает:

perl -anle 'print $F[0] if /^>/ || $_'

Эти четыре опции имеют следующее значение:

  • -n говорит perl неявно циклично выполняться по входным строкам

  • -a говорит жемчугу включать авторазделение, создавая @F массив

  • -l включает автоматическую заканчивающую строку обработку

  • -e говорит этому выполнять команду, которая следует, избавляя от необходимости файл сценария жемчуга.

Сама команда жемчуга довольно читаема:

print $F[0] if /^>/ || $_

Эта команда печатает первое поле, если строка запускается с >. Иначе это печатает целую строку.

7
ответ дан 4 July 2014 в 01:00

Другие вопросы по тегам:

Похожие вопросы: