0

I am trying to create a script that will search through a user input file path and open all the .cix file type and replace line 27.

What I have so far works on individual folders opening the files within one at a time and modifying the desired line. But if I try to use it on a folder with subfolders it's not working. It is opening and saving the file but it's not changing the line and I can't figure out where I am going wrong.

from tkinter import *
import os

root = Tk()
root.geometry('400x75')
root.title('Labels Off')

dirLabel = Label(root, text='Directory Path:').pack()
e = Entry(root, width='50')
e.pack()

os.listdir(path='.')

def replace(filename):
    f = open(filename, 'r')
    lines = f.readlines()
    print(filename)
    f.close()
    if 'ENABLELABEL=1' in lines[27]:
        lines[27] = '   ENABLELABEL=0\n'
    elif 'ENABLELABEL=0' in lines[27]:
        lines[27] = '   ENABLELABEL=1\n'
    else:
        print('err')

    f = open(filename, 'w')
    f.write(''.join(lines))
    f.close()

def getListOfFiles(dirName):
    # create a list of file and sub directories 
    # names in the given directory 
    listOfFile = os.listdir(dirName)
    allFiles = list()
    # Iterate over all the entries
    for entry in listOfFile:
        # Create full path
        fullPath = os.path.join(dirName, entry)
        # If entry is a directory then get the list of files in this directory 
        if os.path.isdir(fullPath):
            allFiles = allFiles + getListOfFiles(fullPath)
        else:
            allFiles.append(fullPath)

    counter = 0
    for file in allFiles:
        if file.endswith('.cix'):
            replace(file)
        else:
            allFiles.pop(counter)
        counter += 1

    return allFiles

def run():
    dirName = e.get()
    getListOfFiles(dirName)
    e.delete(0, END)

submit = Button(root, text='Run', command=run).pack()

mainloop()
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
IHamilton
  • 35
  • 6
  • How do you know that it's opening and saving the file, if it doesn't change the line? – mkrieger1 Mar 24 '20 at 16:39
  • Note that `lines[27]` is the 28th line, not the 27th line (`lines[0]` being the first line). – mkrieger1 Mar 24 '20 at 16:42
  • Yes i am aware that python starts with 0. Thank you though. As for your other question. I can see that it is being opened and saved because the modified date in the file explorer is changing. – IHamilton Mar 24 '20 at 16:48
  • Do you see the `print(filename)` output? And the `err` output? – mkrieger1 Mar 24 '20 at 17:06
  • Yes i do...I put those in while testing trying to figure out whats was going wrong. ***EDIT OH WAIIT... you meant do i see it in the output right? I do see filename in the output but not error. – IHamilton Mar 24 '20 at 17:33
  • And do you see the same filename more than once? – mkrieger1 Mar 24 '20 at 17:38
  • No i only see it once. – IHamilton Mar 24 '20 at 18:31
  • Then it appears the code replacing the lines is executed. How do you know that the lines were not replaced? – mkrieger1 Mar 24 '20 at 18:34
  • UPDATE: OK The very first one only appears once but all the others are showing up twice. So i now understand the problem but what is causing it. I know how to fix it now i just need to remove duplicates. – IHamilton Mar 24 '20 at 18:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210252/discussion-between-ihamilton-and-mkrieger1). – IHamilton Mar 24 '20 at 18:51

2 Answers2

1

OK, i don't know exactly what was wrong with my previous method of creating a file list but something wasn't working right. After trying for a while i replaced my previous method with this and it now works perfectly,

def getListOfFiles(dirName):

    allFiles = []
    for r, d, f, in os.walk(dirName):
        for file in f:
            if '.cix' in file:
                allFiles.append(os.path.join(r, file))


    for file in allFiles:
        replace(file)

    return allFiles
IHamilton
  • 35
  • 6
  • 1
    The difference is the same as what I described in my answer: It separates getting a list of files from calling `replace`. `os.walk` just also replaces the recursion. – mkrieger1 Mar 24 '20 at 21:31
0

getListOfFiles returns a list of files for the current directory and all subdirectories and also calls replace on every .cix file in this list.

But it does this recursively, so for every .cix file that is in a subdirectory one level deeper, replace was already called.

Since replace basically toggles a line between ENABLELABEL=1 and ENABLELABLE=0, for every .cix file that is in a subdirectory that is at an odd number of levels below the root directory, there is effectively no change.

The solution is to first get a complete a list of files and then call replace for each .cix file:

def getListOfFiles(dirName):
    # create a list of file and sub directories 
    # names in the given directory 
    listOfFile = os.listdir(dirName)
    allFiles = list()
    # Iterate over all the entries
    for entry in listOfFile:
        # Create full path
        fullPath = os.path.join(dirName, entry)
        # If entry is a directory then get the list of files in this directory 
        if os.path.isdir(fullPath):
            allFiles = allFiles + getListOfFiles(fullPath)
        else:
            allFiles.append(fullPath)

    # no replace(file) here

    return allFiles

def run():
    dirName = e.get()
    allFiles = getListOfFiles(dirName)

    # instead, do it here
    for file in allFiles:
        if file.endswith('.cix'):
            replace(file)

    e.delete(0, END)

(I also didn't understand what you were trying to achieve with counter. I just omitted it.)

mkrieger1
  • 19,194
  • 5
  • 54
  • 65