Python Forum
Add stdout to text file - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Add stdout to text file (/thread-15696.html)



Add stdout to text file - maxtimbo - Jan-28-2019

Alright, I've tried a great many thing to try to get this to work. This iteration is the closest I've gotten to success. What I'm trying to do is write two lines, and only two lines, to a text file and then create a new file. The format is as such:

file1.txt
file 'C:\path\to\audiofile1.wav'
file 'C:\path\to\audiofile2.wav'

I'm using ffprobe to analyze an undetermined amount of audio tracks and essentially sort them by track length. I was at first trying to write the output ffprobe straight to the text file, but every out put was overwriting the first line and there would only be one file with one line, the last track in the directory. So then I tried to send the output of ffprobe to an array and print that to a text file. That works a little better, but either I only write 1 line to 1 file, or the entire array to only 1 file. Here's my code. I'm exhausted right now, I'll answer any questions and supply more code if you need. You'll see some bits commented out. I tend to leave those in there while I think about what I might change.

clipOrig = "D:\\path\\to\\audio\\files"
os.chdir(clipOrig)

current_files = glob.glob("sFile*.txt")
file_count = 1
file = open(f"sFile{file_count}.txt", "w")

while f"sFile{file_count}.txt" in current_files:
    file_count += 1
arr = []
def write_file():
    global file_count, count
    count = sum(1 for line in open(f"sFile{file_count}.txt"))
    # count = 1
    if(count == 2):
        file_count +=1
        count = 1
    else:
        for i in arr:
            print("file ", f"'{i}'", "\n", file=text_file)
            count += 1

for f in os.listdir():
    ffprobe = subprocess.check_output(['ffprobe', '-v', 'quiet', '-show_entries', 'format=duration', '-of', 'csv=p=0', '-i', f], stderr=subprocess.PIPE, stdin=subprocess.PIPE).decode('utf-8').rstrip()
    with open(f"sFile{file_count}.txt", "w") as text_file:
        if float(ffprobe) < 35:
            ffilename = subprocess.check_output(['ffprobe', '-v', 'quiet', '-show_entries', 'format=filename', '-of', 'csv=p=0', '-i', f]).decode('utf-8').rstrip()
            arr.append(f"{clipOrig}\\{ffilename}")
        else:
            print("false")

write_file()



RE: Add stdout to text file - ichabod801 - Jan-28-2019

I would move the with statement on line 25 outside of the for loop on line 23. It overwrites because you open it each time and write it anew. Open it once an you won't be writing over it each time.

Another thing you can do is open it in mode 'a' (append) rather than mode 'w' (write). Then it will write without writing over.


RE: Add stdout to text file - maxtimbo - Jan-28-2019

(Jan-28-2019, 03:57 AM)ichabod801 Wrote: I would move the with statement on line 25 outside of the for loop on line 23. It overwrites because you open it each time and write it anew. Open it once an you won't be writing over it each time.

Another thing you can do is open it in mode 'a' (append) rather than mode 'w' (write). Then it will write without writing over.

This certainly helped! Thank you, I knew there was one small dumb thing I was missing. So now I'm at this point where I'm writing correctly to a file and only the first two tracks. I thought I would use text_file.close() to close the file to start a new one when the correct number of lines has been written. But then I get ValueError: I/O operation on closed file., which makes sense because, duh!, the file is closed. So how would I then start a new file for the next cycle? Take a look at the modified code:

Note*: I added the print() lines to the if/else statement for debugging.

clipOrig = "C:\\path\\to\\audio\\files"

os.chdir(clipOrig)

current_files = glob.glob("..\\wrkDir\\sFile*.txt")
file_count = 0
sFile = f"..\\wrkDir\\sfile{file_count}.txt"
file = open(sFile, "a")
count = sum(1 for line in open(sFile))

while f"..\\wrkDir\\sfile{file_count}.txt" in current_files:
    file_count += 1

def write_file():
    global file_count, count
    if(count > 1):
        file_count +=1
        print("count is: ", count)
        print("file Count is: ", file_count)
        count = 0
        text_file.close()
    else:
        text_file.write("file ")
        text_file.write(f"'{clipOrig}\\{ffilename}'")
        text_file.write("\n")
        count += 1
        print("else triggered, count is: ", count)
        print("Else triggered, File Count is: ", file_count)

with file as text_file:
    for f in os.listdir():
        ffprobe = subprocess.check_output(['ffprobe', '-v', 'quiet', '-show_entries', 'format=duration', '-of', 'csv=p=0', '-i', f], stderr=subprocess.PIPE, stdin=subprocess.PIPE).decode('utf-8').rstrip()
        if float(ffprobe) < 35:
            ffilename = subprocess.check_output(['ffprobe', '-v', 'quiet', '-show_entries', 'format=filename', '-of', 'csv=p=0', '-i', f]).decode('utf-8').rstrip()
            write_file()
        else:
            print("false")



RE: Add stdout to text file - maxtimbo - Feb-05-2019

I figured this out a while ago. Thought I would share the solution for future browsers/google searchers:

file_count = 0
count = 0

def write_file():
    global file_count, count, sfile
    if(count > 0):
        call_close()
        file_count += 1
        count = 0
    else:
        call_close()
        count += 1

def call_close():
    global file_count, ffilename
    with open(f"{wrkDir}\\sfile{file_count}.txt", "a+") as text_file:
        text_file.write("file ")
        text_file.write(f"'{clipOrig}\\{ffilename}'")
        text_file.write("\n")
        text_file.close()