I'm trying to create a script where it will go through multiple directories and sub directories and find a matching filename and display it's path.
I was able to do this in shell script with ease and i was able to get the desired output. I have used this in shell like this:
echo "enter the name of the movie."
read moviename
cd "D:\movies"
find -iname "*$moviename*" > result.txt
cat result.txt
for i in result.txt
do
if [ "$(stat -c %s "$i")" -le 1 ]
then
echo "No such movie exists"
fi
done
This is what I have in python and i'm getting nowhere.
import os.path
from os import path
print ('What\'s the name of the movie?')
name = input()
for root, dirs, files in os.walk('D:\movies'):
for file in files:
if os.path.isfile('D:\movies'+name):
print(os.path.join(root, file))
else:
print('No such movie')
I want it to search for the filename case insensitive and have it display. I've tried so hard to do it.
import os
name = input('What\'s the name of the movie?')
success = False
for root, dirs, files in os.walk('D:\movies'):
for file in files:
if name.lower() in file.lower():
print(os.path.join(root, file))
success = True
if success == False:
print('No such movie')
You don't need to import each part of os separately.
You can combine input and print into one line.
This is basically asking 'if this string is in that string, print the path'. lower() will make it case insensitive.
I added the success variable as otherwise it will print line for every time a file doesn't match.
You may want to replace the (absolutely meaningless, because you don't compare file with anything):
if os.path.isfile('D:\movies'+name):
with:
if file.lower().find(name.lower()) != -1 :
and have fun with the file list you're getting =)
from pathlib import Path
MOVIES = Path('D:\movies')
def find_file(name)
for path in MOVIES.rglob('*'):
if path.is_file() and name.lower() in path.name.lower():
break
else:
print('File not found.')
path = None
return path
You could also look into the fuzzywuzzy library for fuzzy matching between file names and input name.
Related
I tried to make a program which delete all of the empty files ( whose size is zero ). Then, i run the program by dragging the script file in "command prompt" and run it .
However, no empty files had deleted (but i have some of them).
Please help me to find the error in my code.
import os
a = os.listdir('C:\\Python27')
for folder in a :
sizes = os.stat('C:\\Python27')
b = sizes.st_size
s = folder
if b == 0 :
remove('C:\\Python27\s')
You're assigning the values iterator os.listdir returns to folder and yet you aren't using it at all in os.stat or os.remove, but instead you are passing to them fixed values that you don't need.
You should do something like this:
import os
dir = 'C:\\Python27'
for file_name in os.listdir(dir):
file_path = os.path.join(dir, file_name)
if os.stat(file_path).st_size == 0:
os.remove(file_path)
You can delete something like the following code and you need to add some exception handling. I have used a test folder name to demonstrate.
import os
import sys
dir = 'c:/temp/testfolder'
for root, dirs, files in os.walk(dir):
for file in files:
fname = os.path.join(root, file)
try:
if os.path.getsize(fname) == 0:
print("Removing file %s" %(fname))
os.remove(fname)
except:
print("error: unable to remove 0 byte file")
raise
I have this code that will let the user choose which file he wants to update by passing an argument in the command line, and then it do some more things but I have not included that here:
import sys
import os
from sys import argv
path = "/home/Desktop/python/test"
files = os.walk( path )
filename = argv[1]
if filename in files:
inputFile = open(filename, 'r')
else:
print "no match found"
sys.exit()
inputFile.close()
When I run the script it keeps giving me "no match found" but im pretty sure the file is there. I cant see what Im doing wrong
os.walk() returns a generator, one that produces tuples with (root, directories, files) values for each iteration.
You can't use that generator to test for a single file, not with a simple in membership test.
You'll also need to re-instate the whole path; you can't just open an unclassified filename without the directory it lives in. Just use a for loop here, and break once you found it. The else suite on a for loop only executes when you did not use break (e.g. the file was not found):
path = "/home/Desktop/python/test"
filename = argv[1]
for root, directories, files in os.walk(path):
if filename in files:
full_path = os.path.join(root, filename)
break
else:
print "no match found"
sys.exit()
with open(full_path) as input_file:
# do something with the file
I added a with statement to handle the lifetime of the file object; once the with block is exited the file is automatically closed for you.
Alternatively, you may use following code snippet.
import os.path
filename = argv[1]
path = "/home/Desktop/python/test/"
if os.path.isfile(path + filename):
inputFile = open(path + filename, "r")
else:
print "File Not Found"
I'm attempting to look for a keyword of a text file within a directory then find out the whole name of the file using Python.
Let this keyword be 'file', but this text file in the directory is called 'newfile'.
I'm trying to find out the name of the whole file in order to be able to open it.
import os
keyword = 'file'
for fname in os.listdir('directory/with/files'):
if keyword in fname:
print(fname, "has the keyword")
You could use fnmatch. From the documentation:
This example will print all file names in the current directory with the extension .txt:
import fnmatch
import os
for filename in os.listdir('.'):
if fnmatch.fnmatch(filename, '*.txt'):
print filename
From your example you would want fnmatch(filename, '*file*').
e.g:
>>> from fnmatch import fnmatch
>>> fnmatch('newfile', '*file*')
True
>>> fnmatch('newfoal', '*file*')
False
Using grep you can locate file containing the word you are looking for.
grep -r 'word' FOLDER
-r indicates grep to look for 'word' in all the files of FOLDER
I am wondering why this wouldn't work, Its suppose to return a list with one item which is the full path of a file. But if the user input path is a directory its suppose to return a list with all files in it.
The problem is it doesn't throw an error it just stops like its expecting another input. I have tried to debug but its hard to find because it keeps changing. I will comment all lines in english to to read what I assume/want the code to do
import re
import os, glob
# Program to extract emails from text files
def path_file():
path = raw_input("Please enter path to file:\n> ") ## /home/gatsby/think/lead/
if os.path.exists(path):
print "Working" # doesn't print this infact it just freezes without an error message
if os.path.isfile(path):
print "test file"
return glob.glob(path)
else:
print "test dir"
print os.path.normpath(path) + os.sep ## for debugging
return glob.glob(os.path.normpath(path) + os.sep + '*.*')
#else:
#raise SystemError
All,
What is the best way to check to see if there is data in a directory before deleting it? I am browsing through a couple pages to find some pics using wget and of course every page does not have an image on it but the directory is still created.
dir = 'Files\\%s' % (directory)
os.mkdir(dir)
cmd = 'wget -r -l1 -nd -np -A.jpg,.png,.gif -P %s %s' %(dir, i[1])
os.system(cmd)
if not os.path.isdir(dir):
os.rmdir(dir)
I would like to test to see if a file was dropped in the directory after it was created. If nothing is there...delete it.
Thanks,
Adam
import os
if not os.listdir(dir):
os.rmdir(dir)
LBYL style.
for EAFP, see mouad's answer.
I will go with EAFP like so:
try:
os.rmdir(dir)
except OSError as ex:
if ex.errno == errno.ENOTEMPTY:
print "directory not empty"
os.rmdir will not delete a directory that is not empty.
Try:
if not os.listdir(dir):
print "Empty"
or
if os.listdir(dir) == []:
print "Empty"
This can now be done more efficiently in Python3.5+, since there is no need to build a list of the directory contents just to see if its empty:
import os
def is_dir_empty(path):
with os.scandir(path) as scan:
return next(scan, None) is None
Example usage:
if os.path.isdir(directory) and is_dir_empty(directory):
os.rmdir(directory)
What if you did checked if the directory exists, and whether there is content in the directory... something like:
if os.path.isdir(dir) and len(os.listdir(dir)) == 0:
os.rmdir(dir)
If the empty directories are already created, you can place this script in your outer directory and run it:
import os
def _visit(arg, dirname, names):
if not names:
print 'Remove %s' % dirname
os.rmdir(dirname)
def run(outer_dir):
os.path.walk(outer_dir, _visit, 0)
if __name__ == '__main__':
outer_dir = os.path.dirname(__file__)
run(outer_dir)
os.system('pause')
Here is the fastest and optimized way to check if the directory is empty or not.
empty = False
for dirpath, dirnames, files in os.walk(dir):
if files:
print("Not empty !") ;
if not files:
print("It is empty !" )
empty = True
break ;
The other answers mentioned here are not fast because , if you want use the usual os.listdir() , if the directory has too many files , it will slow ur code and if you use the os.rmdir( ) method to try to catch the error , then it will simply delete that folder. This might not be something which u wanna do if you just want to check for emptyness .
I have follews Bash checking if folder has contents answer.
Mainly it is similiar approach as #ideasman42's answer on https://stackoverflow.com/a/47363995/2402577, in order to not to build the complete list, which would probably work on Debian as well.
there is no need to build a list of the directory contents just to
see if its empty:
os.walk('.') returns the complete files under a directory and if there thousands it may be inefficient. Instead following command find "$target" -mindepth 1 -print -quit returns first found file and quits. If it returns an empty string, which means folder is empty.
You can check if a directory is empty using find, and processing its
output
def is_dir_empty(absolute_path):
cmd = ["find", absolute_path, "-mindepth", "1", "-print", "-quit"]
output = subprocess.check_output(cmd).decode("utf-8").strip()
return not output
print is_dir_empty("some/path/here")