2013-12-16 3 views
2

Я пытаюсь, по-моему, реплицировать функциональность оболочки Linux в cat как агностик, так что я могу взять два текстовых файла и объединить их содержимое в следующим образом:добавить содержимое из одного файла в другой с расстановкой новой строки

file_1 содержит:

42 bottles of beer on the wall 

file_2 содержит:

Beer is clearly the answer 

Merged файл должен содержать:

42 bottles of beer on the wall 
Beer is clearly the answer 

Большинство методов, которые я читал о том, однако, в конечном итоге производство: 42 бутылок пива на wallBeer явно ответ

Другая проблема заключается в том, что фактические файлы, с которыми я Мне нравится работать с невероятно большими текстовыми файлами (FASTA отформатированные файлы последовательности белка), так что я думаю, что большинство методов, читающих строки за строкой, неэффективны. Таким образом, я пытался выяснить, решение с использованием shutil, как показано ниже:

def concatenate_fasta(file1, file2, newfile): 
    destination = open(newfile,'wb') 
    shutil.copyfileobj(open(file1,'rb'), destination) 
    destination.write('\n...\n') 
    shutil.copyfileobj(open(file2,'rb'), destination) 
    destination.close() 

Однако это приводит к тем же проблемам, как раньше, за исключением «...» между ними. Ясно, что новые строки игнорируются, но я не понимаю, как правильно их управлять.

Любая помощь была бы очень признательна.

EDIT:

Я попытался предложение Мартейн, но значение line_sep Возвращается None, который выдает ошибку, когда функция пытается записать, что в выходной файл. Я получил эту работу прямо сейчас через os.linesep методу, изложенному в менее оптимален следующим образом:

with open(newfile,'wb') as destination: 
    with open(file_1,'rb') as source: 
     shutil.copyfileobj(source, destination) 
    destination.write(os.linesep*2) 
    with open(file_2,'rb') as source: 
     shutil.copyfileobj(source, destination) 
    destination.close() 

Это дает мне необходимые мне функции, но я все еще на немного потери, почему (по-видимому более элегантный) решение не работает.

+2

Это не ответ, но 'file1',' Параметры file2' не соответствует 'file_1',' file_2' в теле функции. – falsetru

+0

Какие методы вы пытались читать по строкам? – Totem

+0

@falsetru Ух, да, это было плохо. Спасибо, что поймали его. Исправленный. – glarue

ответ

3

Вы открыли файлы в двоичном режиме, поэтому перевод новой строки не будет выполнен. На разных платформах используются разные окончания строк, и если вы находитесь на Windows \n, то не достаточно.

Самый простой метод должен был бы написать os.linesep здесь:

destination.write(os.linesep + '...' + os.linesep) 

но может нарушить фактическую конвенцию новой строки, используемые в файлах.

Лучше подход будет открывать текстовые файлы в текстовом режиме, прочитать одну или две строки, а затем проверить file.newlines attribute, чтобы увидеть, что соглашение является для этого файла:

def concatenate_fasta(file_1, file_2, newfile): 
    with open(file_1, 'r') as source: 
     next(source, None) # try and read a line 
     line_sep = source.newlines 
     if isinstance(line_sep, tuple): 
      # mixed newlines, lets just pick the first one 
      line_sep = line_sep[0] 

    with open(newfile,'wb') as destination 
     with open(file_1,'rb') as source: 
      shutil.copyfileobj(source, destination) 
     destination.write(line_sep + '...' + line_sep) 

     with open(file_2,'rb') as source: 
      shutil.copyfileobj(source, destination) 

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

+0

Большое спасибо за тщательный ответ; Сегодня я сделаю этот снимок. Я сохранил эту часть своего сценария для последнего, думая: «Это должно быть тривиально, чтобы объединить два файла вместе». Живи и учись. – glarue

+0

Не работает (см. Обновленный OP); ваше другое предложение, похоже, сделало трюк, хотя мне интересно, может ли он сломать что-то по линии, как вы предостерегаете. – glarue

+1

@glarue: Возможно, вам нужно прочитать более одной строки; возможно, сделайте это циклом, читающим несколько строк, до тех пор, пока не будет установлено значение 'source.newlines', с максимальным количеством строк, прежде чем вы откажетесь. –

1

Кажется, что ваши исходные файлы не могут заканчиваться символом новой строки.В таком сценарии было бы полезно прочитать последний символ (или больше на основе вашей платформы) файла, чтобы определить, есть ли его новый строковый символ (ы) os.linesep и, соответственно, добавить новую строку в выходной файл.

with open("file1.txt",'rb') as fin1, \ 
    open("file2.txt",'rb') as fin2, \ 
    open("file3.txt",'wb') as fout: 
    shutil.copyfileobj(fin1, fout) 
    fin1.seek(-len(os.linesep), 2) 
    if fin1.read() != os.linesep: 
      fout.write(os.linesep) 
    shutil.copyfileobj(fin2, fout) 
0
from sys import argv 
from os.path import exists 

script, from_file, to_file = argv 

print "Copying from %s to %s" % (from_file, to_file) 

# we could do these two on one line too, how? 
in_file = open(from_file, 'rb') 
indata = in_file.read() 


print "Ready, hit RETURN/ENTER to continue, CTRL- C to abort." 
raw_input() 

out_file = open(to_file, 'a') 

out_file.write(indata) 
print "Alright, all done." 

out_file.close() 
in_file.close()