как заменить n-й столбец строкой, разделенной столбцами, с помощью sed/awk

Вот так:

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--
-3
09.09.2021, 09:51
1 ответ

Чтобы заменить 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"
0
09.09.2021, 10:15

Теги

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