1

I have a tab-delimited txt file.

I want to remove n-th row of tab-delimited txt.

I will assign like

n = 1

then the program will remove just the first row of the file.

If the program does it without even reading the whole input file, then it would be fantastic.

I tried to learn from one of my previous questions:

Concatenate tab-delimited txt files vertically

This question was vertically concatenating two tab-delimited txt files. So I thought reversing this process will do something similar for me. But I couldn't find how to do it.

I also tried many other stackoverflow answers.

But they are mostly 'removing lines that have specific phrase' rather than 'removing n-th line'

(How to delete a line from a text file using the line number in python, Deleting a specific line in a file (python), Deleting a line from a file in Python)

Community
  • 1
  • 1
user3123767
  • 1,115
  • 3
  • 13
  • 22
  • 1
    Unless the lines are all the same length, read all lines and print all of them except the one you want to remove. – tripleee Jul 24 '14 at 06:11
  • 1
    possible duplicate of [How to delete a line from a text file using the line number in python](http://stackoverflow.com/questions/17747522/how-to-delete-a-line-from-a-text-file-using-the-line-number-in-python) – tripleee Jul 24 '14 at 06:11
  • @tripleee Although that question's title says about deleting using line number, that question isn't actually. That question is explicitly assigning "phrase = 'the dog barked'" and deleting lines with that phrase. – user3123767 Jul 24 '14 at 06:18
  • @tripleee The input file's lines have same length. In other words, all rows have the same number of columns. Then is it possible not to read all lines and remove n-th row? – user3123767 Jul 24 '14 at 06:19
  • Then it's possible to do it more efficiently by seeking to that particular offset and rewrite the file. But unless you can rewrite with a dummy record (or a real record of data) and leave the remainder of the file intact, I don't think it will be worth the effort. – tripleee Jul 24 '14 at 06:42
  • Several of the answers to the proposed duplicate show you how to replace a line given its offset in the file. The accepted solution has a comment (by yours truly) showing how to adapt it. The `mmap` solution shows some promise to be faster but is significantly more complex. – tripleee Jul 24 '14 at 06:44
  • But by "same length" I mean the same number of bytes on each line. (It would not be a valid TSV file if it had a variable number of fields.) – tripleee Jul 24 '14 at 06:50

2 Answers2

1
lineToRemove = 7

f = open("yourfile.txt","r")
lines = f.readlines()
f.close()

f = open("yourfile.txt","w")
linesInFile = 0
for line in lines:
    linesInFile = linesInFile + 1
    if linesInFile != lineToRemove:
        f.write(line)
f.close()

Edit: By using del and omitting explicit open and close we can reduce the code:

lines = file("yourfile.txt", "r").readlines()
del lines[6]
file("yourfile.txt", "w").writelines(lines)

Please note that del lines[6] removes the 7th line because the index begins with zero. So, here's a convenient function we could use:

def deleteLine(filename, lineToRemove):
    lines = file(filename, "r").readlines()
    del lines[lineToRemove-1]
    file(filename, "w").writelines(lines)
Jens Wirth
  • 17,110
  • 4
  • 30
  • 33
  • Thank you! This works perfectly. However, does this program reads whole input file? The input file's lines have same length. In other words, all rows have the same number of columns. Then is it possible not to read all lines and remove n-th row? – user3123767 Jul 24 '14 at 06:23
  • How is this efficient in any way? – Ashwini Chaudhary Jul 24 '14 at 08:38
1

You can use itertools.islice for this. Here no Python for-loop is involved so it should be fast:

from itertools import islice

n = 4
with open('file.txt') as f, open('out.txt', 'w') as out:
    out.writelines(islice(f, n-1)) #write the lines before the nth line
    out.writelines(islice(f, 1, None)) #write the rest of the lines except nth
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504