简体   繁体   中英

Read lines from a text file, reverse and save in a new text file

So far I have this code:

 f = open("text.txt", "rb")
 s = f.read()
 f.close()
 f = open("newtext.txt", "wb")
 f.write(s[::-1])
 f.close()

The text in the original file is:

This is Line 1
This is Line 2
This is Line 3
This is Line 4

And when it reverses it and saves it the new file looks like this:

 4 eniL si sihT 3 eniL si sihT 2 eniL si sihT 1 eniL si sihT

When I want it to look like this:

 This is line 4
 This is line 3
 This is line 2
 This is line 1

How can I do this?

You can do something like:

with open('test.txt') as f,  open('output.txt', 'w') as fout:
    fout.writelines(reversed(f.readlines()))

read() returns the whole file in a single string. That's why when you reverse it, it reverses the lines themselves too, not just their order. You want to reverse only the order of lines, you need to use readlines() to get a list of them (as a first approximation, it is equivalent to s = f.read().split('\\n') ):

s = f.readlines()
...
f.writelines(s[::-1])
# or f.writelines(reversed(s))
f = open("text.txt", "rb")
s = f.readlines()
f.close()
f = open("newtext.txt", "wb")
s.reverse()
for item in s:
  print>>f, item
f.close()

There are a couple of steps here. First we want to get all the lines from the first file, and then we want to write them in reversed order to the new file. The code for doing this is as follows

lines = []
with open('text.txt') as f:
    lines = f.readlines()

with open('newtext.txt', 'w') as f:
    for line in reversed(lines):
        f.write(line)

Firstly, we initialize a variable to hold our lines. Then we read all the lines from the 'test.txt' file. Secondly, we open our output file. Here we loop through the lines in reversed order, writing them to the output file as we go.

The method file.read() returns a string of the whole file, not the lines.

And since s is a string of the whole file, you're reversing the letters, not the lines!

First, you'll have to split it to lines:

s = f.read()
lines = s.split('\n')

Or:

lines = f.readlines()

And your method, it is already correct:

f.write(lines[::-1])

Hope this helps!

Use it like this if your OS uses \\n to break lines

f = open("text.txt", "rb")
 s = f.read()
 f.close()
 f = open("newtext.txt", "wb")
 f.write(reversed(s.split("\n")).join("\n"))
 f.close()

Main thing here is reversed(s.split("\\n")).join("\\n") .

It does the following:

  1. Split your string by line breaks - \\n ,
  2. resulting an array
  3. reverses the array
  4. merges the array back with linebreaks \\n to a string

Here the states:

  1. string: line1 \\n line2 \\n line3
  2. array: ["line1", "line2", "line3"]
  3. array: ["line3", "line2", "line1"]
  4. string: line3 \\n line2 \\n line1 \\n

A sample using list so it will be much easier: I'm sure there answer that are more elegant but this way is clear to understand.

f = open(r"c:\test.txt", "rb")
s = f.read()
f.close()

rowList = []
for value in s:
    rowList.append(value + "\n")
rowList.reverse()


f = open(r"c:\test.txt", "wb")

for value in rowList:
    f.write(value)
f.close()

You have to work line by line.

f = open("text.txt", "rb")
s = f.read()
f.close()
f = open("newtext.txt", "wb")
lines = s.split('\n')
f.write('\n'.join(lines[::-1]))
f.close()

If your input file is too big to fit in memory, here is an efficient way to reverse it:

  1. Split input file into partial files (still in original order).
  2. Read each partial file from last to first, reverse it and append to output file.

Implementation:

import os
from itertools import islice

input_path = "mylog.txt"
output_path = input_path + ".rev"

with open(input_path) as fi:
    for i, sli in enumerate(iter(lambda: list(islice(fi, 100000)), []), 1):
        with open(f"{output_path}.{i:05}", "w") as fo:
            fo.writelines(sli)

with open(output_path, "w") as fo:
    for file_index in range(i, 0, -1):
        path = f"{output_path}.{file_index:05}"
        with open(path) as fi:
            lines = fi.readlines()
        os.remove(path)
        for line in reversed(lines):
            fo.write(line)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM