0

I will start off by saying that I have seen the answers to a similar question. I have attempted to use this for my problem, but I am unable to get it to function properly.

I have multiple .xyz files with the same prefix and suffix starting from 0. There is potential to be 100+ files, so not defining them individually is essential. I need to merge/concatenate/append these files in numerical order to a merged.xyz. For example:

output0.xyz:

H 1.0 1.0 1.0

output1.xyz:

H 2.0 2.0 2.0

merged.xyz:

H 1.0 1.0 1.0
H 2.0 2.0 2.0

I have tried this as a simple test case:

tempfiles = ['output0.xyz', 'output1.xyz']

f = open("bigtextfile.xyz", "w")
for tempfile in tempfiles:
    f.write(tempfile.read())

But I get:

Traceback (most recent call last):
  File "Test.py", line 28, in <module>
    f.write(tempfile.read())
AttributeError: 'str' object has no attribute 'read'

An alternative I have attempted:

prefix = "output"
suffix = ".xyz"

count = 0
while count <= 1:
    for filename in os.listdir('./'):
        if filename.endswith(suffix):

            xyzFile = open(prefix + str(count) + suffix, "r")
            lines = xyzFile.readlines()
            xyzFile.close()

            merged = open("merged" + suffix, "a")
            for line in lines:
                merged.write(line)
            merged.close()
    count += 1

But it copies the first file twice, and the second three times:

H 1.0 1.0 1.0
H 1.0 1.0 1.0
H 2.0 2.0 2.0
H 2.0 2.0 2.0
H 2.0 2.0 2.0

How do you suggest I move forward? I am leaning towards the second solution, as it already automatically gets the contents of the files in numerical order. Please let me know if you need any additional details and how to improve the question.

kskinnerx16
  • 127
  • 5

2 Answers2

1

You have:

tempfiles = ['output0.xyz', 'output1.xyz']

f = open("bigtextfile.xyz", "w")
for tempfile in tempfiles:
    f.write(tempfile.read())

But tempfile in your loop is being assigned the name of a file, such as 'output0.xyz', and being a string it has no method read; you need to use that as an argument to open:

tempfiles = ['output0.xyz', 'output1.xyz']

with open("bigtextfile.xyz", "w") as f:
    for tempfile in tempfiles:
        with open(tempfile) as infile:
            f.write(infile.read())

Note that I am using with context managers, which will automatically close the files when the blocks they govern terminate.

Update

This code will try to process files ouput0.xyz, output1.xyz, ... and will terminate until it gets an open error. It does not explicitly read the directory but rather assumes that the files are contiguously number 0, 1, 2 ... N:

from itertools import count


with open("bigtextfile.xyz", "w") as f:
    for suffix in count(0): # suffix takes on values 0, 1, 2, ...
        try:
            with open(f'output{suffix}.xyz') as infile:
                f.write(infile.read())
        except Exception:
            break # get out of loop when we can no longer open outputN.xyz for some value N
Booboo
  • 38,656
  • 3
  • 37
  • 60
-1
tempfiles = ['output0.xyz', 'output1.xyz']

with open("bigtextfile.xyz", "w") as f:
    for tempfile in tempfiles:
        with open(tempfile, 'r') as temp:
            f.write(temp.read())
    
Aaj Kaal
  • 1,205
  • 1
  • 9
  • 8
  • And how is this different from my answer? – Booboo Oct 27 '20 at 14:42
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Dharman Oct 27 '20 at 17:24