Замена каждой n-й строки в одном файле следующей строкой из другого файла в bash

#bash #awk #sed #replace #while-loop

#bash #awk #sed #заменить #цикл while

Вопрос:

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

Файл 1:

 1: Read 1
2: Sequence 1
3:  
4: Quality 1
5: Read 2
6: Sequence 2 
7:  
8: Quality 2
...
  

Файл 2:

 1: Sequence 1 edited
2: Sequence 2 edited
3: Sequence 3 edited
4: Sequence 4 edited
...
  

Начиная со строки 2 первого файла, мне нужно заменить каждую 4-ю строку следующей прочитанной строкой во втором файле, чтобы результат выглядел следующим образом:

 1: Read 1
2: Sequence 1 edited
3:  
4: Quality 1
5: Read 2
6: Sequence 2 edited 
7:  
8: Quality 2
...
  

До сих пор я использовал этот код, который, кажется, работает, но медленный как команда и болезненный как сценарий оболочки:

 Counter=2
while read p; do echo $Counter; echo $p; 
    sed -i~ "${Counter}s/^.*/$p/" file 1; 
    Counter=$((Counter 4)); done < file 2
  

Я думаю, что смогу сделать это с помощью awk, но я не уверен, как. Будем признательны за любую помощь или улучшения!

Комментарии:

1. Пожалуйста, разбейте однострочный текст на несколько строк для удобства чтения.

Ответ №1:

Предполагая, что номера строк приведены только для пояснения и не включены в файлы, пожалуйста, попробуйте следующее:

 awk 'NR==FNR {line[NR]=$0; next} {if (FNR%4==2) $0=line[  count]; print}' file2 file1
  

Вывод:

 Read 1
Sequence 1 edited
 
Quality 1
Read 2
Sequence 2 edited
 
Quality 2
...
  

[Пояснения]

  • Условие NR==FNR совпадает только при чтении file2 и сохраняет строки в массиве line по порядку.
  • Следующая {if ... инструкция выполняется только при чтении file1 . Если номер строки file1 равен 2 с модулем 4, строка заменяется содержимым массива line .

Комментарии:

1. Ваше предположение было правильным — извините за отсутствие ясности. Кажется, это помогает, и намного быстрее! Большое спасибо за вашу помощь!

2. Приятно знать, что это помогло вам.

Ответ №2:

Другое решение с использованием awk и вставки

 awk ' { print "n" $0 "n" "n" } ' file2.txt | 
     paste - file1.txt | awk -F"t" ' {x=NR%4==2 ? $1 : $2; print x } '
  

с заданными входными данными

 $ cat cmswen1.txt
Read 1
Sequence 1
 
Quality 1
Read 2
Sequence 2
 
Quality 2

$ cat cmswen2.txt
Sequence 1 edited
Sequence 2 edited
Sequence 3 edited
Sequence 4 edited

$ awk ' { print "n" $0 "n" "n" } ' cmswen2.txt | 
     paste - cmswen1.txt | awk -F"t" ' {x=NR%4==2 ? $1 : $2; print x } '
Read 1
Sequence 1 edited
 
Quality 1
Read 2
Sequence 2 edited
 
Quality 2

Sequence 3 edited



Sequence 4 edited



$