How would you scan a dir for a text file and read the text file by date modified, print it to screen having the script scan the directory every 5 seconds for a newer file creadted and prints it.
Is it possible that you can help me i'm stuck and i need this real bad and i've already got the scan dir for file and print but it does not print the files by date modidfied.
import os,sys
os.chdir(raw_input('dir_path: ') )
contents=os.listdir('.') #contents of the current directory
files =[]
directory=[]
Time = time.ctime(os.path.getmtime(contents))
for i in contents:
if os.path.isfile(i) == True :
files.append(i)
elif os.path.isdir(i) == True :
directory.append(i)
#printing contents
choice = ""
for j in files:
while choice != "quit":
choice = raw_input("Dou you want to print file %s (y/n): "%j)
if choice == 'y':
print "**************************"
print "Printing Files %s" %j
print "**************************"
fileobj = open(j,'r')
contents = fileobj.readlines()
for k in contents:
sys.stderr.write(k)
else:
pass
what i wanted is instead of my code asking if it wants to print i need it to print the files if modified by the current time meaning if it read a file that was just placed in the directory and a new one comes in it will read the new file without prompting me.
the error it's giving me is coercing to unicode: need string or buffer, list found.
Repeating actions on a timer
You can repeat an action every five seconds by combining an infinite loop with the time.sleep() function, like so:
import time
while True:
time.sleep(5) # wait five seconds
print (time.time()) # print the time
Remember to have some kind of break condition in here if you need it, otherwise the loop will run forever.
"TypeError: coercing to Unicode: need string or buffer, list found"
Your problem is in the line
Time = time.ctime(os.path.getmtime(contents))
You have provided a list of filenames. The os.path.getmtime function expects one filename at a time. The error message is telling you that it has no idea how to convert a list of filenames into a filename.
Related
I'm trying to monitor a CSV file that is being written to by a separate program. Around every 10 seconds, the CSV file is updated with a couple more lines. Each time the file is updated, I want to be able to detect the file has been changed (will always be the same file), take the new lines, and write them to console (just for a test).
I have looked around the website, and have found numerous ways of watching a file to see if its updated (like so http://thepythoncorner.com/dev/how-to-create-a-watchdog-in-python-to-look-for-filesystem-changes/), but I can't seem to find anything that will allow me to get to the changes made in the file to print out to console.
Current code:
import time
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
def on_created(event):
print(f"hey, {event.src_path} has been created!")
def on_deleted(event):
print(f"Someone deleted {event.src_path}!")
def on_modified(event):
print(f"{event.src_path} has been modified")
def on_moved(event):
print(f"ok ok ok, someone moved {event.src_path} to {event.dest_path}")
if __name__ == "__main__":
patterns = "*"
ignore_patterns = ""
ignore_directories = False
case_sensitive = True
my_event_handler = PatternMatchingEventHandler(patterns, ignore_patterns, ignore_directories, case_sensitive)
my_event_handler.on_created = on_created
my_event_handler.on_deleted = on_deleted
my_event_handler.on_modified = on_modified
my_event_handler.on_moved = on_moved
path = "."
go_recursively = True
my_observer = Observer()
my_observer.schedule(my_event_handler, path, recursive=go_recursively)
my_observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
my_observer.stop()
my_observer.join()
This runs, but looks for changes in files all over the place. How do I make it listen for changes from one single file?
If you're more or less happy with the script other than it tracking a bunch of files then you could change the patterns = "*" part which is a wildcard matching string which tells the PatternMatchingEventHandler to look for any file. You could change that to paterns = 'my_file.csv' and also change the path variable to the directory that the file is in to save some time recursively scanning all the directories in '.'. Then you don't need recursive set to True for a single file either.
Print new lines to console part (one option):
import pandas as pd
...
def on_modified(event):
print(f"{event.src_path} has been modified")
# You said "a couple more lines" I'm going to take that
# as two:
df = pd.read_csv(event.src_path)
print("Newest 2 lines:")
print(df[-2:])
If it's not two lines you'll want to track the length of the file and pass that to the function which opens the CSV so it knows how many lines are new.
I believe since this is a CSV file, reading file using pandas and checking the file size can help. You can use df.tail(2) to print last two rows after reading the csv using pandas
I am trying to print line-by-line per file that is inside a list.
At the end of each line of the file, it needs to check if the term ".sh" is in it or not.
I am getting the error
"Tail: Write error: "Broken Pipe"
Expected result:
Read each from list
Check each line of the file if the term ".sh" comes in it at the end of the line of the file.
Prints if it finds the ".sh"
This is what I have atm:
# Modules
import os
from pprint import pprint
# Files in list
dirlist = ['test.txt','test2.txt','test3.txt']
# Loop to read the file in list
for x in range (len(dirlist)):
print ("Output of Filename: " + dirlist[x]
# Variable to save the last 3 characters of the line
last3 = os.popen ("cat " + dirlist[x] + " | tail -c 3")
print last3
# Read file
f = open(dirlist[x], "r")
# Loop to check if the keyword is the same as last3
for l in f:
if last3 in l:
print ("FOUND IT!")
else:
print ("NOT IN IT!")
Outcome:
#Nic
[![enter image description here][3]][3]
I suggest that you use with environment with native python code instead of open and os.popen
Here is an example
# Files in list
dirlist = ['test.txt','test2.txt','test3.txt']
# Loop to read the file in list
for x in dirlist:
print ("Output of Filename: " + x)
with open(x) as f
lines=f.readlines()
for line in lines: #here you print each line
print (line)
if '.sh' in lines[-1:]: #check if .sh is in the last line
print("found it")
else:
print("didnt find it")
os.popen returns a file object, not a string.
See: Assign output of os.system to a variable and prevent it from being displayed on the screen
tail (actually stdio) gives the "Broken Pipe" error when it tries to write output but there's nobody around to read it. (More specifically, when it receives SIGPIPE.)
If you're going to launch a child process with popen, you need to finish reading from the pipe before your program exits.
In your case, you should probably use subprocess.run rather than a bare os.popen.
Or, better yet, don't use a subprocess for simple file operations! Just do them in native Python code, and it will be much simpler.
With the help Of #Nic Wanavit and Daniel Pyrden, I finally fixed it.
I've put the if/else inside the loop, otherwise it would check all the lines for the .sh instead of per line.
and I've put parenthesis inside the ".sh" section and that worked!
However, I did not do it in the last 3 characters, because the -1: wasn't working for me for some reason.
# Files in List
dirlist = ['test.txt', 'test2.txt', 'test3.txt']
# Loop to read the file in list
for x in dirlist:
print ("Output of filename: "+ x)
with open(x) as f:
lines = f.readlines()
for line lines:
print ("Line in file: " + line)
if (".sh" in line):
print ("FOUND IT")
else:
print ("not found it \n")
Result
I have the following code:
print "We're going to write to a file you'll be prompted for"
targetfile = raw_input('Enter a filename: ')
targetfilefound = open('targetfile' , 'w')
print "What do we write in this file?"
targetfilefound.write("hello this is working!")
targetfilefound.close()
The script I'm creating should be able to write to a file that the user defines via raw_input. The above could be faulty at core, open to suggestions.
Judging by the stuff the script is printing you probably want the user to input what should be printed to the file so:
print "We're going to write to a file you'll be prompted for"
targetfile = raw_input('Enter a filename: ')
targetfilefound = open(targetfile , 'w')
print "What do we write in this file?"
targetfilefound.write(raw_input())
targetfilefound.close()
Note: This method will create the new file if it does not exist. If you want to check whether the file exists you can use the os module, something like this:
import os
print "We're going to write to a file you'll be prompted for"
targetfile = raw_input('Enter a filename: ')
if os.path.isfile(targetfile) == True:
targetfilefound = open(targetfile , 'w')
print "What do we write in this file?"
targetfilefound.write(raw_input())
targetfilefound.close()
else:
print "File does not exist, do you want to create it? (Y/n)"
action = raw_input('> ')
if action == 'Y' or action == 'y':
targetfilefound = open(targetfile , 'w')
print "What do we write in this file?"
targetfilefound.write(raw_input())
targetfilefound.close()
else:
print "No action taken"
As pointed out by others, remove the quotes from target file as you have assigned it already to a variable.
But actually instead of writing as code you can use the with open as given below
with open('somefile.txt', 'a') as the_file:
the_file.write('hello this is working!\n')
In the above case, you don't need to do any exception handling while processing the file. When-ever an error occurs the file cursor object is automatically closed and we dont need to explicitly close it. Even it writing to file it success, it will automatically close the file pointer reference.
Explanation of efficient use of with from Pershing Programming blog
Okay so I'm trying to write a script that takes two files and modifies the first before writing it into the destination fine, but whenever I run it, the script only prints the first modified line over and over again.
#3a
def modify(string):
"""Takes a string and returns a modified version of the string using two modifications. One must be a replacement of some kind.
string -> string"""
while string != "":
string = string.upper()
string = string.replace("A","4").replace("B","8").replace("C","<").replace("E","3").replace("G","6").replace("I","1").replace("O","0").replace("R","|2").replace("S","5").replace("T","7").replace("Z","2")
print(string)
#3b - asks the user to type in a source code filename and destination filename; opens the files; loops through the contents of the source file line-by-line, using modify() to modify eat line before writing it to the destination file; the closes both files.
source = input("What file would you like to use?")
destination = input("Where would you like it to go?")
filesource = ""
while filesource == "":
try:
file_source = open(source, "r")
file_destination = open(destination, "w")
for item in file_source:
mod = modify(item)
file_destination.write(mod)
file_source.close()
file_destination.close()
break
except IOError:
source = input("I'm sorry, something went wrong. Give me the source file again please?")
Any help?
Hint: if you run modify("TEST ME") what does it return?
add return string to the end of the modify function.
The string never empties - try parsing through it char by char using an index int and your conditional being while i < len(string)
I try to write a script than scan recursive a given directory and if found mp3 get and just print meta tag for it. What ever I passed to getEyeD3Tag I got an exception. Here is my code that i have written so far
def getEyeD3Tags(path):
try:
trackInfo = eyeD3.Mp3AudioFile(path)
tag = trackInfo.getTag()
tag.link(path)
print tag.getArtist()
print tag.getAlbum()
print tag.getTitle()
#return (tag.getArtist(),tag.getTitle(),tag.getAlbum())
except eyeD3.InvalidAudioFormatException:
print "File %s is not a mp3 file " % path
mp3Num=0
temp=os.walk(valid-folder-name)
for root, dirs, files in temp:
for i in files:
if os.path.join(root,i):
temp=os.path.splitext(i)
temp[1].lower()
if temp[1]=='.mp3':
mp3Path=os.path.join(root,i)
print mp3Path
getEyeD3Tags(mp3Path)
mp3Num+=1
raw_input()
#print "**"
else:
print "Error invalid path"
print "\n\n"
#raw_input()
print mp3Num
raw_input()
And BTW is it a way to get genre of mp3 file using eyeD3?
Thx in advance
To check if the file being parsed is a valid mp3, call the eyeD3.isMp3File(filename) method.
The following is from a short script I made to auto-sort my music folder.
def parseIDETag(self, path):
if eyeD3.isMp3File(path):
That way, if the file isn't an mp3, it'll just skip over it.
Also, str(tag.getGenre()) returns the genre as a string using eyeD3.