1

I have a text file that will have the contents:

Line 1
,
,
Line 2
,
Line 3
,
Line 4

I would like to create a function that deletes the empty spaces between the lines (marked with , for illustration)

So far, I've created a function with the following code, but nothing happens when I run this:

with open('path/to/file.txt', 'r') as f: 
    for line in f:           
        line = line.strip()  

Any help is appreciated.

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
Rutnet
  • 1,533
  • 5
  • 26
  • 48
  • 1
    Even if it would strip the lines, but here it doesn't since you iterate over the lines, you do not store the values in (another) file. – Willem Van Onsem Nov 05 '20 at 22:15
  • 1
    You may want to write the result into another file, whenever `if line:` – tevemadar Nov 05 '20 at 22:15
  • Isn't there a way of removing the blank lines from the existing file without writing to a new one? – Rutnet Nov 05 '20 at 22:17
  • 3
    You can't 'edit' a file, only read, append or write over it – Judev1 Nov 05 '20 at 22:21
  • You can read the whole file into memory, close the file, open it again for writing, and write its new contents from what you have in memory. – CryptoFool Nov 05 '20 at 23:02
  • Does this answer your question? [How to delete all blank lines in the file with the help of python?](https://stackoverflow.com/questions/2369440/how-to-delete-all-blank-lines-in-the-file-with-the-help-of-python) – Gino Mempin Nov 05 '20 at 23:26

7 Answers7

5

If you want to remove blank lines from an existing file without writing to a new one, you can open the same file again in read-write mode (denoted by 'r+') for writing. Truncate the file at the write position after the writing is done:

with open('file.txt') as reader, open('file.txt', 'r+') as writer:
  for line in reader:
    if line.strip():
      writer.write(line)
  writer.truncate()

Demo: https://repl.it/@blhsing/KaleidoscopicDarkredPhp

blhsing
  • 91,368
  • 6
  • 71
  • 106
3

You need to override the file after changing:

with open('path/to/file.txt', 'r') as f:  
    new_text = '\n'.join([line.strip() for line in f.read().split('\n')] if line.strip())
    with open('path/to/file.txt','w') as in_file: 
        in_file.write(new_text)
adir abargil
  • 5,495
  • 3
  • 19
  • 29
2

The line.strip() will only strip that line, but that does not mean that if the line is empty the line somehow will disappear. Furthermore you never really store the (processed) line in (another) file.

You can process the file and write the result to a target.txt file with:

with open('path/to/file.txt', 'r') as f:
    with open('path/to/target.txt', 'w') as w:
    for line in f:
        if line.strip():
            w.write(line)

If you want to strip non-empty lines as well, so remove leading and trailing spaces from all lines, you can use the stripped variant:

with open('path/to/file.txt', 'r') as f:
    with open('path/to/target.txt', 'w') as w:
    for line in f:
        line = line.strip()
        if line:
            w.write(line)
            w.write('\n')

This program will read the file line-by-line, which is often better for huge files, since loading a huge file in memory, can result in memory problems.

Furthermore it is often better to store the result in another file. If the machine crashes while processing (for example due to power failure), then you still have the original file. Most Linux commands are designed to write to another file. Such that later, when the operation is done, you move the target to the original file.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • This make sense, thank you. In your example, how would I write the changes back to the original file. Can I replace target.txt to file.txt – Rutnet Nov 05 '20 at 22:36
  • 1
    @Rutnet: in that case you better move the new file to the source file *after* processing it, for example with [**`os.rename`**](https://docs.python.org/3/library/os.html#os.rename). Since then you still have low memory usage, and furthermore if the machine goes down while writing, you will always have or the original file, or the result file, but not something that is half processed (and thus with the rest of the content lost). – Willem Van Onsem Nov 05 '20 at 22:39
  • Amazing, works flawlessly – Rutnet Nov 05 '20 at 22:43
  • @WillemVanOnsem The second solution will incorrectly strip all newline characters so the output becomes one long line. – blhsing Nov 05 '20 at 23:09
  • 1
    @blhsing: thanks, updated. – Willem Van Onsem Nov 05 '20 at 23:10
1

I would approach that like this:

with open('path/to/file.txt', 'r+') as f:
    lines = f.readlines()
    lines = [line.strip() for line in lines]
    f.writelines(line)
Judev1
  • 434
  • 3
  • 11
1

You can remove the empty lines like this:

with open("txt.txt", "r") as f:
  for l in f:
    if l == "\n":
      l = l.replace("\n", "")
    with open("output.txt", "a") as f2:
        f2.write(l)
User
  • 141
  • 1
  • 9
0

If you want to remove blank lines from an existing file without writing to a new one, you can use random access instead. Open the file in read-write binary mode, keep track of the file's read position with the file.tell method as you read line by line, keep track of the file's write position when you write a non-blank line, restore the read and write positions when you read and write with the file.seek method, and finally, use the file.truncate method to truncate the file at the last write position:

write_position = 0
with open('file.txt', 'rb+') as f:
  for line in f:
    if line.strip():
      read_position = f.tell()
      f.seek(write_position)
      f.write(line)
      write_position = f.tell()
      f.seek(read_position)
  f.truncate(write_position)

Demo: https://repl.it/@blhsing/UncommonRevolvingTransversals

blhsing
  • 91,368
  • 6
  • 71
  • 106
-1
with open('path/to/file.txt', 'r') as f: #this opens the file in read mode
    lines = [line for line in f.readlines() if line.strip() != ""] #this puts all the lines of the file into a nice list, but removes every line that is empty. 

with open('path/to/file.txt', 'w') as f: #this just clears the contents
    pass 

for line in lines: #this goes through the lines list
    with open('path/to/file.txt', 'a') as f: #this opens the file append mode
        f.write(f'{line.strip()}\n') #this strips the line, and adds it at the end of the file and creates a new line
Epic Gamer
  • 101
  • 1
  • 10
  • You. don't need to go through all that. If you just open the file in 'w' mode, and then write to it, it won't matter what was in the file before. No need to clear it first. No need to use append mode. – CryptoFool Nov 05 '20 at 23:06