Вот так:
paste file1.fa file2.fa |
sed -E 's/\s+>/-/; s/\s+//g' |
awk -v c=0 '{ if(/^>/){c++} print > "file"c".pasted.fa"; }'
Чтобы объяснить это, давайте посмотрим, что выводит каждая команда:
$ paste file1.fa file2.fa
>ID_000_FLNNKGHD_01376 >ID_000_KGHDAAD_06245
-ATGAATACAGAGGAAAAAACACCGCTTGCATACAAT AAATACAGAGGAAAAAACACCGCTTGCATACAAT
>ID_000_MGCDKLCO_02388 >ID_000_KOAAFG_40481
ATGAAGGTGGAAAAAACACCGCTTGCATTT CCCCAGGAAGGTGGAAAAAACACCGCTTGCAAA
>ID_000_OMAMOGKP_02746 >ID_000_GPAAAGVV_07764
--ATGTTGGTGGAAAAAACACCGCTTGCGGTA --AAATTGGTGG---------ACACCGCTTTT--
Так что это будет печатать каждую строку из каждого файла рядом друг с другом. Строка 1 из файла 1 со строкой 1 из файла 2, строка 2 из файла 1 со строкой 2 из файла 2 и т. д. Однако в ней есть лишние пробелы и лишний >
, от которых нам нужно избавиться. Вот что делает sed
:
$ paste file1.fa file2.fa | sed -E 's/\s+>/-/; s/\s+//'
>ID_000_FLNNKGHD_01376-ID_000_KGHDAAD_06245
-ATGAATACAGAGGAAAAAACACCGCTTGCATACAATAAATACAGAGGAAAAAACACCGCTTGCATACAAT
>ID_000_MGCDKLCO_02388-ID_000_KOAAFG_40481
ATGAAGGTGGAAAAAACACCGCTTGCATTTCCCCAGGAAGGTGGAAAAAACACCGCTTGCAAA
>ID_000_OMAMOGKP_02746-ID_000_GPAAAGVV_07764
--ATGTTGGTGGAAAAAACACCGCTTGCGGTA--AAATTGGTGG---------ACACCGCTTTT--
Последний шаг, скрипт awk
будет:
awk -v c=0
:запустите awk
и установите для переменной c
значение 0
. if(/^>/){c++}
:добавляйте 1 к значению c
каждый раз, когда мы находим строку, начинающуюся с >
. print > "file"c".pasted.fa"
:вывести текущую строку в файл с именем file
, затем текущее значение c
и .pasted.fa
. Окончательный результат при запуске вашего примера::
$ ls *pasted*
file1.pasted.fa file2.pasted.fa file3.pasted.fa
$ cat file1.pasted.fa
>ID_000_FLNNKGHD_01376-ID_000_KGHDAAD_06245
-ATGAATACAGAGGAAAAAACACCGCTTGCATACAATAAATACAGAGGAAAAAACACCGCTTGCATACAAT
$ cat file2.pasted.fa
>ID_000_MGCDKLCO_02388-ID_000_KOAAFG_40481
ATGAAGGTGGAAAAAACACCGCTTGCATTTCCCCAGGAAGGTGGAAAAAACACCGCTTGCAAA
$ cat file3.pasted.fa
>ID_000_OMAMOGKP_02746-ID_000_GPAAAGVV_07764
--ATGTTGGTGGAAAAAACACCGCTTGCGGTA--AAATTGGTGG---------ACACCGCTTTT--
Чтобы заменить plk="1234"
на plk="789"
, вы можете сделать:
$ sed 's/plk="1234"/plk="789"/g' file
xyz="123" ; acd="234" ; plk="789" ; apl="3456" ; www="2342"
Однако это также заменит notplk="1234"
на plk="789"
. Чтобы избежать этого, вы можете использовать \<
, чтобы он совпадал только на границах слов :
$ sed 's/\<plk="1234"/plk="789"/g' file
xyz="123" ; acd="234" ; plk="789" ; apl="3456" ; www="2342"
Не уверен, что \<
на 100% портативный, так что на всякий случай тоже можно сделать:
$ sed -E 's/(^| )plk="1234"/plk="789"/g' file
xyz="123" ; acd="234" ;plk="789" ; apl="3456" ; www="2342"
или вместо этого используйте Perl:
$ perl -pe 's/\bplk="1234"/plk="789"/g' file
xyz="123" ; acd="234" ; plk="789" ; apl="3456" ; www="2342"
Со всеми вышеуказанными командами, как sed
, так и perl
, вы можете добавить флаг -i
для редактирования исходного файла на месте.
Приведенные выше команды заменят все вхождения plk="1234"
в каждой строке файла. Вы не объясняете в своем вопросе, но в своем заголовке упоминаете «n-й столбец». Я не знаю, как вы определяете столбцы или что вы подразумеваете под этим, но если вы имеете в виду, что хотите сделать эту замену только в 3-м;
-столбце с разделителями, вы можете попробовать это (с GNUawk
):
$ awk -F';' 'BEGIN{OFS=";"}{$3=gensub(/plk="1234"/,"plk=\"789\"",1,$3); }1' file
xyz="123" ; acd="234" ; plk="789" ; apl="3456" ; www="2342"