Как вставить другой заголовок для каждой строки с sed?

7

Мне нужно изменить текстовый файл с 770 строками и добавить другой заголовок для каждого из них, например, у меня есть это:

CWGAGATCGGAAGAGCGGTTCAGCAGGAATGCCGAG
ACACTCTTTCCCTACACGACGCTCTTCCGATCTAGGC
ACACTCTTTCCCTACACGACGCTCTTCCGATCTGATT
ACACTCTTTCCCTACACGACGCTCTTCCGATCTACCGT

И я хочу получить это:

>seq1
CWGAGATCGGAAGAGCGGTTCAGCAGGAATGCCGAG
>seq2
ACACTCTTTCCCTACACGACGCTCTTCCGATCTAGGC
>seq3
ACACTCTTTCCCTACACGACGCTCTTCCGATCTGATT
>seq4
ACACTCTTTCCCTACACGACGCTCTTCCGATCTACCGT
    
задан Idalia Rojas 18.08.2017 в 19:43
источник

4 ответа

13

Поскольку вы специально попросили решение sed (я бы не предлагал на самом деле делать это так, но вы могли):

$ sed = file | sed '1~2 s/^/>seq/'
>seq1
CWGAGATCGGAAGAGCGGTTCAGCAGGAATGCCGAG
>seq2
ACACTCTTTCCCTACACGACGCTCTTCCGATCTAGGC
>seq3
ACACTCTTTCCCTACACGACGCTCTTCCGATCTGATT
>seq4
ACACTCTTTCCCTACACGACGCTCTTCCGATCTACCGT

Первый вызов sed = file вставляет номера голых строк, а второй украшает их, добавляя строку >seq .

OTOH, если вы заранее знаете, что есть 770 строк, вы могли бы сделать

printf ">seq%d\n" {1..770} | sed 'R file'

, хотя это зависит от расширения GNU sed R :

  

R имя файла
  Очередь - строка имени файла, которая должна быть прочитана и вставлена ​​в вывод   поток в конце текущего цикла или когда следующая строка ввода   читать. Обратите внимание, что если имя файла не может быть прочитано или если его конец достигнут,   строка не добавляется, без каких-либо ошибок.

Конечно, если вы не знаете количество строк раньше времени, вы могли делать

printf ">seq%d\n" $(seq 1 "$(wc -l < file)") | sed 'R file'

, но это потеряло бы преимущество только в том, что нужно было только один раз прочитать файл.

На практике я, вероятно, использовал решение awk @ John1024 awk или его эквивалент perl

perl -lpe 'print ">seq" . $.' file
    
ответ дан steeldriver 18.08.2017 в 19:56
источник
12

Ваша задача может быть выполнена с помощью sed, но sed не имеет никакого собственного понимания арифметики, что делает ее неправильным инструментом. Awk работает хорошо:

$ awk '{print ">seq" NR} 1' file
>seq1
CWGAGATCGGAAGAGCGGTTCAGCAGGAATGCCGAG
>seq2
ACACTCTTTCCCTACACGACGCTCTTCCGATCTAGGC
>seq3
ACACTCTTTCCCTACACGACGCTCTTCCGATCTGATT
>seq4
ACACTCTTTCCCTACACGACGCTCTTCCGATCTACCGT

Как это работает:

  • print ">seq" NR

    Для каждой новой строки мы сначала печатаем требуемый заголовок.

    NR - счетчик строк awk.

  • 1

    Это критическое сокращение awk для печати. ​​

ответ дан John1024 18.08.2017 в 19:48
источник
5

Используя простой цикл:

count=1; while read -r line ; do printf '>seq%d\n%s\n' $((count++)) "$line"; done < file

Выход:

>seq1
CWGAGATCGGAAGAGCGGTTCAGCAGGAATGCCGAG
>seq2
ACACTCTTTCCCTACACGACGCTCTTCCGATCTAGGC
>seq3
ACACTCTTTCCCTACACGACGCTCTTCCGATCTGATT
>seq4
ACACTCTTTCCCTACACGACGCTCTTCCGATCTACCGT
    
ответ дан Ravexina 18.08.2017 в 19:54
источник
0

Использование paste :

 paste -d '\n' <(seq -f '>seq%g' 1 4) file
  • seq -f '>seq%g' 1 4 записывает числа, разделенные символом строки в stdout
  • & lt; (...) - замещение процесса
  • paste объединяет соответствующую строку каждого файла, разделяемую разделителем
  • -d '\n' устанавливает разделитель конкатенации в новую строку вместо закладки по умолчанию
ответ дан gardenhead 18.08.2017 в 21:58
источник

Ознакомьтесь с другими вопросами по меткам