3

I am trying to convert a txt file into a csv file in Python. The current format of the txt file are several strings separated by spaces. I would like to write each string into one cell in the csv file.

The txt file has got following structure:

UserID Desktop Display (Version) (Server/Port handle), Date

UserID Desktop Display (Version) (Server/Port handle), Date

etc.

My approach would be following:

with open('licfile.txt', "r+") as in_file:
    stripped = (line.strip() for line in in_file)
    lines = (line.split(" ") for line in stripped if line)

with open('licfile.csv', 'w') as out_file:
    writer = csv.writer(out_file)
    writer.writerow(('user', 'desktop', 'display', 'version', 'server', 'handle', 'date'))
    writer.writerows(lines)

Unfortunately this is not working as expected. I do get following ValueError: I/O operation on closed file. Additionally only the intended row headers are shown in one cell in the csv file.

Any tips on how to proceed? Many thanks in advance.

3
  • 2
    can you add an input and an expected output example please? Commented Sep 19, 2019 at 11:53
  • You should include the input and output of the script (or some part of it). Commented Sep 19, 2019 at 11:57
  • Just use read_lines = in_file.readlines() before stripped = (line.strip() for line in in_file) to read the lines in the buffer before iterating over them. Otherwise, the logic of the code seems good enough. Commented Sep 19, 2019 at 12:55

4 Answers 4

3

how about

with open('licfile.txt', 'r') as in_file, open('licfile.csv', 'w') as out_file:
    for line in in_file:
        if line.strip():
            out_file.write(line.strip().replace(' ', ',') + '\n')

and for the german Excel enthusiasts...

...
    ...
        ...
            ... .replace(' ', ';') + '\n')

:)

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the hint. This solution at least writes the data into the csv but unfortunately writes everything into one column, I would like to separate each record from the others.
What do you understand by column? It puts commas inbetween all entries where were spaces before. If you define column by what-is-put-in-different-columns-when-I-load-that-csv-with-Excel then you should have a look what Excel uses as column separator. You're in Germany? Try ;...
Yes (not only, but also) in Germany the standard decimal sign is a comma, which is unfortunately exactly the same character which is used as a column separator in - well, comma separated value -files. Therefore the column separator is here a semicolon. This is part of the locale preferences topic with software in general.
You guessed right, thanks for the explanation. Now if I have got several rows in the txt file with equivalent columns, can I simply add that after every date a new row shall be started?
Yes, all records are printed in one line but I would like to have one row per entry in the text file.
|
1

You can also use the built in csv module to accomplish this easily:

import csv

with open('licfile.txt', 'r') as in_file, open('licfile.csv', 'w') as out_file:
    reader = csv.reader(in_file, delimiter=" ")  
    writer = csv.writer(out_file, lineterminator='\n')
    writer.writerows(reader)

I used lineterminator='\n' argument here as the default is \r\n and it ends up giving you an extra line of return per row in most cases.

There are also a few arguments you could use if say quoting is needed or a different delimiter is desired: https://docs.python.org/3/library/csv.html#csv-fmt-params

Comments

1

You are using comprehension with round brackets which will cause to create tuple object. Instead of that just use square bracket which will return list. see below example:

stripped = [line.strip() for line in in_file]
lines = [line.split(" ") for line in stripped if line]

1 Comment

No sorry, but this is simply wrong. round brackets with a for-expression result in a generator, not in a tuple. and even though OP probably did that by accident, this is imo not the problem here...
0
licfile_df = pd.read_csv('licfile.txt',sep=",", header=None)

3 Comments

@shaikmoeed I think there's some misunderstanding - spaces are the separators in the source file. Target file should be a csv, which by standard is generally comma separated. AFAIU this is in fact the main conversion which the whole post is about...
using pandas it is so easy to convert text file into DataFrame and sep="," is for if your text file is seprated by comma , It varies according to your text file.
Yes, correct it's easy from usability point of view. But on the one handside it might be a little too heavy library for a simple task like this and then this post is simply not tagged with pandas...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.