Я совсем недавно начал использовать 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*
Я представляю здесь четыре решения, два использования 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 /^>/ || $_
Эта команда печатает первое поле, если строка запускается с >
. Иначе это печатает целую строку.