перемежать строки двух разных файлов - PullRequest
1 голос
/ 17 февраля 2012

Мне нужно выполнить простое задание, но я не знаю, как это сделать, и меня поставили на карту. Мне нужно чередовать строки двух разных файлов каждые 4 строки:

Файл 1:

1
2
3
4
5
6
7
8
9
10
11
12

ФАЙЛ 2:

A
B
C
D
E
F
G
H
I
J
K
L

Желаемый результат:

1
2
3
4
A
B
C
D
5
6
7
8
E
F
G
H
9
10
11
12
I
J
K
L

Я ищу сценарий sed, awk или python или любую другую команду bash.

Спасибо за ваше время !!

Я пытался сделать это, используя специальные библиотеки Python, которые распознают 4-строчные модули каждого файла. Но это не работает, и теперь я пытаюсь сделать это без этих библиотек, но не знаю как.

import sys
from Bio import SeqIO
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord


def main(forward,reverse):

    for F, R in zip ( SeqIO.parse(forward, "fastq"), SeqIO.parse(reverse, "fastq") ):

        fastq_out_F = SeqRecord( F.seq, id = F.id, description = "" )
        fastq_out_F.letter_annotations["phred_quality"] = F.letter_annotations["phred_quality"]

        fastq_out_R = SeqRecord( R.seq, id = R.id, description = "" )
        fastq_out_R.letter_annotations["phred_quality"] = R.letter_annotations["phred_quality"]

        print fastq_out_F.format("fastq"),
        print fastq_out_R.format("fastq"),


if __name__ == '__main__':
    main(sys.argv[1], sys.argv[2])  

Ответы [ 5 ]

3 голосов
/ 17 февраля 2012

Это может работать для вас: (с помощью GNU sed)

sed -e 'n;n;n;R file2' -e 'R file2' -e 'R file2' -e 'R file2' file1

или с использованием paste / bash:

paste -d' ' <(paste -sd'   \n' file1) <(paste -sd'   \n' file2) | tr ' ' '\n'

или:

parallel -N4 --xapply 'printf "%s\n%s\n" {1} {2}'  :::: file1 :::: file2
1 голос
/ 17 февраля 2012

Смесь paste и sed также можно использовать, если у вас нет GNU sed:

paste -d '\n' f1 f2 | sed -e 'x;N;x;N;x;N;x;N;x;N;x;N;x;N;s/^\n//;H;s/.*//;x'

Если вы не знакомы с sed, есть 2-йбуфер называется пространством удержания, где вы можете сохранить данные.Команда x обменивает текущий буфер с пространством удержания, команда N добавляет одну строку к текущему буферу, а команда H добавляет текущий буфер к пространству удержания.

Так чтосначала x;N сохранить текущую строку (из f1 из-за paste) в области удержания и прочитать следующую строку (из f2 из-за paste), затем каждый x;N;x;N читает новую строку из f1 и f2,и сценарий завершается удалением новой строки из 4 строк f2, помещает строки из f2 в конец строк f1, очищает место удержания для следующего запуска и печатает 8 строк.

1 голос
/ 17 февраля 2012

Это можно сделать в чистом виде:

f1=""; f2=""
while test -z "$f1" -o -z "$f2"; do
  { read LINE && echo "$LINE" && \
      read LINE && echo "$LINE" && \
      read LINE && echo "$LINE" && \
      read LINE && echo "$LINE"; } || f1=end;
  { read -u 3 LINE && echo "$LINE" && \
      read -u 3 LINE && echo "$LINE" && \
      read -u 3 LINE && echo "$LINE" && \
      read -u 3 LINE && echo "$LINE"; } || f2=end;
done < f1 3< f2

Идея состоит в том, чтобы использовать новый дескриптор файла (в данном случае 3) и одновременно читать из stdin и этот дескриптор файла.

0 голосов
/ 17 февраля 2012

Попробуйте, изменив соответствующие значения имени файла для f1 и f2.

awk 'BEGIN{
  sectionSize=4; maxSectionCnt=sectionSize; maxSectionCnt++
  notEof1=notEof2=1
  f1="file1" ; f2="file2"
   while (notEof1 && notEof2) {
    if (notEof1) {
      for (i=1;i<maxSectionCnt;i++) {
        if (getline < f1 >0 ) { print "F1:" i":" $0 } else {notEof1=0}
      }
    }
    if (notEof2) {
      for (i=1;i<maxSectionCnt;i++) {
        if (getline < f2 >0 ) { print "F2:" i":" $0 } else {notEof2=0}
      }
    }
  }
}'

Вы также можете удалить заголовок записи "F1: i":" и т.д. Я добавил, что помощь отладки кода.

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

Надеюсь, это поможет.

0 голосов
/ 17 февраля 2012

Код, который вы разместили, выглядит чрезвычайно сложным. При программировании есть практическое правило: всегда есть более простое решение. В вашем случае, способ проще.

Первое, что вы должны сделать, это определить ограничения ввода. Собираетесь ли вы обрабатывать действительно большие файлы? Или они будут размером только один или два килобайта? Это имеет значение.

Второе: посмотрите на инструменты, которые у вас есть . С Python у вас есть файловые объекты, списки, генераторы и так далее. Попробуйте объединить эти инструменты для получения желаемого результата.

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

Взгляните на файловый объект , xrange , нарезка списка и понимание списка . Если вы предпочитаете делать это круто , вы также можете взглянуть на модуль itertools .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...