-1

I'm trying to create a function to copy lines from one file, remove the first omit_from_start and last omit_from_end lines from the file, and write the remaining lines to a new file.

This is what I've tried:

def truncate_file(file1, file2):
#    file1 = "omit_lines_test.txt"    # Just for testing
#    file2 = "truncated_file.txt"    # Just for testing
    infile = open(file1, "r")
    outfile = open(file2, "w")

    print("\n*** Truncating file copy ***\n")
    omit_from_start = int(input("Omit how many lines from the start: "))
    omit_from_end = int(input("Omit how many lines from the end: "))

    lines_to_output = []

    lines = [line for line in infile]
    lines_to_output.append(str(lines[omit_from_start:omit_from_end]))

    for line in lines_to_output:
        for character in line:
            outfile.write(character)

    infile.close()
    outfile.close()

my infile is just a text file containing ['1\n', '2\n', '3\n', '4\n', '5\n', '6\n', '7\n', '8\n', '9\n', '10\n'], and I need the outfile to contain, for example, ['4\n', '5\n', '6\n', '7\n', '8\n'] for omit_from_start = 3 and omit_from_end = 2.

At the moment, lines_to_output just contains ['[]']. I've also tried using the .join() and .pop() methods, but they don't produce what I'm after, either.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Jim421616
  • 1,434
  • 3
  • 22
  • 47
  • @eyllanesc: the question you've linked to talks about searching through each lines to find a particular string. I'm just trying to omit ranges of lines. As you can see, I've tried to slice the `lines` list. – Jim421616 Apr 29 '18 at 22:29
  • 1
    Possible duplicate of [Remove lines from textfile with python](https://stackoverflow.com/questions/2064184/remove-lines-from-textfile-with-python) – eyllanesc Apr 29 '18 at 22:31
  • 1
    You probably wanted either `lines[omit_from_start:-omit_from_end]` or `lines[omit_from_start:len(line)-omit_from_end]` (depending on what you want to do for 0). – abarnert Apr 29 '18 at 22:32
  • Also, since you're doing this by reading the whole file into a list of lines, and output a list of lines to another file, the file part isn't relevant—any answer on how to remove elements from the beginning and end of a _list_ will help you. Which is an easier problem (you've already written the hard part). – abarnert Apr 29 '18 at 22:33

1 Answers1

0

This approach does do an additional scan of the infile to find the number of lines, but it does have the benefit of not having to keep the entire infile in memory during the copy. So it maybe be slower than the original approach for smaller files, but will allow the approach to work on very large files.

def file_len(fname):
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1

def truncate_file(file1, file2):
    infile = open(file1, "r")
    outfile = open(file2, "w")

    print("\n*** Truncating file copy ***\n")
    omit_from_start = int(input("Omit how many lines from the start: "))
    omit_from_end = int(input("Omit how many lines from the end: "))

    length = file_length(file1)

    # This iteration prevents whole file being stored in memory
    for i, line in enumerate(infile):
        if i < omit_from_start:
            continue;
        elif i < length - omit_from_end:
            outfile.write(line)
        elif
           break

    infile.close()
    outfile.close()

Didn't actually run the code, so might be some boundary bugs, but the approach is to scan the infile for the length of file, then iterate over the inline file again, omitting the starting lines and then break the iteration when reaching the length - omit_from_end string.

Did no do any input validation to confirm that omit_from_start is between zero and less than length minus omit_from_end or that omit_from_end is less than length - omit_from_start

Steve Wilhelm
  • 6,200
  • 2
  • 32
  • 36