#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
$