I wanted to supply python with a windows 'data path' that could be used to set up input processing. I googled this with no luck, and now figure I am on my own.
There appears to be many ways of reading in a file with python, and after some frustration with "\" and "/" and windows path names I found a way to get my data path set up. It is not a general approach but should serve me well.
Related Questions: Is this code ugly? Is this a nonstandard method? Are there elegant features in 3.6 that should be used?
### Title: Process an input file using a 'data path' for a user on windows
import sys
import os
print("OK, starting program...")
file_processed = False
for path, dirs, files in os.walk("/Users/Mike"):
if file_processed: break
for file in files:
if file_processed: break
if file == 'seriousdata.txt':
my_path = os.path.abspath(path)
my_dsn = os.path.join(my_path, file)
print("Opening txt file " + my_dsn + " for input.")
with open(my_dsn) as da_lines:
textlines = (line.rstrip('\r\n') for line in da_lines)
for line in textlines:
print(line)
file_processed = True
if file_processed:
pass
else:
print("File not found")
print("OK, program execution has ended.")
sys.exit() # END SAMPLE CODE SNIPPET
From looking at your code, I'm assuming that you want to start at one directory, and move through each child directory, printing out the matching filename's contents if it is found.
If so, then this is way to do this with recursion:
import os
def recursive_list(path, filename):
files = os.listdir(path)
for name in files:
try:
p = os.path.join(path, name)
if os.path.isdir(p):
recursive_list(p, filename)
else:
if name == filename:
with open(p, "r") as f:
print(f.read())
except PermissionError:
pass
return
recursive_list("/home/jebby/Desktop","some_file.txt")
This will start out listing files in path. For every file that is found, if that file is a directory, then the function itself is called (Starting at the path to that folder). If filename matches the name of any file in the current directory, it will be printed (if the user has permissions for that file).
Otherwise, if you only want to read the filename from a known directory without walking down the directory tree:
import os
data_path = "/home/jebby/Desktop"
file_you_want = "filename.txt"
with open(os.path.join(data_path, file_you_want), "r") as f:
content = f.read()
print(content)
The main question would be : Do you know the location of the file?
Jebby has an answer to crawl through the directories.
Here is a solution without using "import os"
dir_fullpath = "c:/project_folder/data"
dir_path = "data"
filename = "file.txt"
try:
f = open(dir_path + "/" + filename, 'r')
# print("open " +dir_path + "\" + filename)
# data=[]
for line in f:
print (line.rstrip())
# data.append(line.rstrip())
f.close()
except IOError:
print("Fail to open" + dir_path + "\" + filename)
Related
I want to move files from one directory to another from a .txt file containing the names of the files to be moved, the script must first browse the directory and if it finds the file it moves it to the new directory. Where to start? I've managed to do this for a file list but I'd like to do it directly via the .txt file without rewriting the names of the files to be moved
import shutil, os
files = ['file1.txt', 'file2.txt', 'file3.txt', 'file4.txt']
for file in files:
shutil.move(file, 'destination_directory')
As I know, U cant move your files with .txt
Just move your file_path
You can use my code below.
I have double checked and it work on my side.
Sorry for my poor English Skill :)
import os
import shutil
from pathlib import Path
def create_directory(dir_name: str):
"""To create directory before create files: txt, csv..."""
system_path = os.getcwd()
dir_path = os.path.join(system_path, dir_name)
try:
os.makedirs(dir_path, exist_ok=True)
except OSError as error:
print("Directory '%s' can not be created" % dir_name)
return dir_path
def create_files(dir_path: str, file_name: str):
"""Function for creating files"""
file_path = dir_path + fr"\{file_name}"
with open(file_path, "w") as open_file:
if Path(file_path).is_file():
print(f'File: {file_name} created successfully')
else:
print(f'File: {file_name} does not exist')
open_file.close() # Need to close.
return file_path
def main():
# Step 1: Creating file1.txt, file2.txt, file3.txt, file4.txt
file_one = create_files(create_directory("file1_dir"), 'file1.txt')
file_two = create_files(create_directory("file2_dir"), 'file2.txt')
file_three = create_files(create_directory("file3_dir"), 'file3.txt')
file_four = create_files(create_directory("file4_dir"), 'file4.txt')
# Step 2: Creating destination_directory:
destination_dir = create_directory('destination_directory')
files = [file_one, file_two, file_three, file_four]
# Step 3: Moving Your Files:
for file in files:
shutil.move(file, destination_dir)
if __name__ == "__main__":
main()
For my class I have to write code that will receive a pathname and then display the file contents if its a file or display each file and its contents if a directory is the pathname.
I wrote the following code, which works fine when I test it with my own local directory. But when I run the checks on my class portal it returns an error "No such file or directory".
Can anyone help me see what's wrong with my code?
import os
def openFyle(filename):
openFile = open(filename)
return openFile.read()
def displayFiles(filename):
if os.path.isdir(filename):
os.chdir(filename)
print("Directory name:", os.getcwd())
dirLyst = os.listdir(filename)
for file in dirLyst:
if os.path.isfile(file):
return print("File name:", file, openFyle(file))
elif os.path.exists(file) and os.path.isdir(file):
os.chdir(file)
displayFiles(os.getcwd())
else:
print("File name:", filename, openFyle(filename))
def main():
#while True:
filename = input("Enter a pathname: ")
displayFiles(filename)
if __name__ == "__main__":
main()
Using the os module:
import os
def print_all_file_contents(directory):
for root, dirs, files in os.walk(directory):
for file in files:
print(open(os.path.join(root, file)).read())
if __name__ == "__main__":
print_all_file_contents(input("Enter a directory:"))
What I would guess is, one of the tests they're using on your function is to send an invalid path. In your function, you only cover two cases: either its a path or its a file and you print out the file name with its contents. What if you cant find that file? That else should be an elif that does the os.path.isfile, and then an else in case its an invalid path.
This should fix it.
def displayFiles(filename):
if os.path.isdir(filename):
os.chdir(filename)
print("Directory name:", os.getcwd())
dirLyst = os.listdir(filename)
for file in dirLyst:
if os.path.isfile(file):
return print("File name:", file, openFyle(file))
elif os.path.exists(file) and os.path.isdir(file):
os.chdir(file)
displayFiles(os.getcwd())
elif os.path.isfile(filename):
print("File name:", filename, openFyle(filename))
else:
print("Invalid input")
. I think the portal runs automated tests that pass it path names.
Sure, but that doesn't prevent it from giving you invalid input data, such as non-str or Path-like objects or non existing locations
Also, rather than using chdir, create the absolute path as you go using path.join
def displayFiles(filename):
if filename and os.path.exists(filename):
if os.path.isdir(filename):
print("Directory name:", filename)
for file in os.listdir(filename):
child = os.path.join(filename,file)
displayFiles(child)
else:
print("File name:", filename, openFyle(filename))
else:
print("Invalid input")
Almost any time you're working with file system paths in Python, I recommend pathlib, because it's awesome. It doesn't make a huge difference this this case, but getting used to using it will make things much easier when you need to, say, join multiple paths together.
from pathlib import Path
def display_file(path):
print(f'File: {path}\n')
print(path.read_text())
print('\n\n')
if __name__ == '__main__':
path = Path(input('Enter a pathname: '))
if path.is_dir():
for item in path.iterdir():
# This avoids attempting to print hidden files, which may exist
# depending on the OS / filesystem.
if item.is_file() and not item.name.startswith('.'):
display_file(item)
elif path.is_file():
display_file(path)
The code only tries to print contents if the path is in fact a file or a directory; it displays nothing if passed an invalid or nonexistant path.
I'm trying to loop through some files in a directory. If the filename has two specific strings together, then I'm supposed to open and read those files for information. However, if none of the files have those two strings, I want to print an error message only once.
for filename in os.listdir(directory):
if filename.find("<string1>") != -1 and filename.find("<string2>") != -1:
#open file
else:
#print error message
I know doing this will print as many error messages as there are files in the directory (i.e. if there's 15 files with no matches, I'll get 15 error messages). But what I want is to only print an error message once after there aren't any matches in any of the N files in directory. I figured I could do something like this:
for filename in os.listdir(directory):
if filename.find("<string1>") != -1 and filename.find("<string2>") != -1:
#open file
else:
if filename[-1]: #if filename is last in directory
#print error message
But I've discovered this doesn't work. How would I get an error message to print only after the last filename has been read and doesn't match?
A simple solution would be to initialize some boolean flag before your for loop, e.g. found = false
If you find a file, set found = true. Then you can check the value of found after your for loop finishes and print the appropriate message based on its value.
Filter the list of files before the for-loop:
filenames = [fname for fname in os.listdir(directory)
if '<string1>' in fname and '<string2>' in fname]
if filenames:
for filename in filenames:
#open file
else:
#print error message
You can probably also use the glob module to get the filenames:
import glob
filenames = glob.glob(directory + '/*string1*string2*')
Another way is to use a variable to check if all the files have been processed. Checked and found it working in Python 2.7
import os
directory = "E:\\test\\"
files_count = len(os.listdir(directory))
files_processed = 0
for filename in os.listdir(directory):
if 'string1' in filename and 'string2' in filename:
#open file
print ("Opening file")
else:
files_processed = files_processed + 1
if (files_processed >= files_count):
print ("error message")
Not sure if this is extreme. But I'd make it a function and raise IOError.
Plus, i'd always use absolute path. Try the pathlib module too
import os
def get_files(directory):
for filename in os.listdir(directory):
if "string1" in filename and "string2" in filename:
yield filename
raise IOError("No such file")
for file in get_files('.'):
print(file)
# do stuff with file
I need to read the contents of a file from the list of files from a directory with os.listdir. My working scriptlet is as follows:
import os
path = "/Users/Desktop/test/"
for filename in os.listdir(path):
with open(filename, 'rU') as f:
t = f.read()
t = t.split()
print(t)
print(t) gives me all the contents from all the files at once present in the directory (path).
But I like to print the contents on first file, then contents of the second and so on, until all the files are read from in dir.
Please guide ! Thanks.
You can print the file name.
Print the content after the file name.
import os
path = "/home/vpraveen/uni_tmp/temp"
for filename in os.listdir(path):
with open(filename, 'rU') as f:
t = f.read()
print filename + " Content : "
print(t)
First, you should find the path of each file using os.path.join(path, filename). Otherwise you'll loop wrong files if you change the variable path. Second, your script already provides the contents of all files starting with the first one. I added a few lines to the script to print the file path and an empty line to see where the contents end and begin:
import os
path = "/Users/Desktop/test/"
for filename in os.listdir(path):
filepath = os.path.join(path, filename)
with open(filepath, 'rU') as f:
content = f.read()
print(filepath)
print(content)
print()
os.listdir returns the name of the files only. you need to os.path.join that name with the path the files live in - otherwise python will look for them in your current working directory (os.getcwd()) and if that happens not to be the same as path python will not find the files:
import os
path = "/Users/Desktop/test/"
for filename in os.listdir(path):
print(filename)
file_path = os.path.join(path, filename)
print(file_path)
..
if you have pathlib at your disposal you can also:
from pathlib import Path
path = "/Users/Desktop/test/"
p = Path(path)
for file in p.iterdir():
if not file.is_file():
continue
print(file)
print(file.read_text())
I have a python script parse.py, which in the script open a file, say file1, and then do something maybe print out the total number of characters.
filename = 'file1'
f = open(filename, 'r')
content = f.read()
print filename, len(content)
Right now, I am using stdout to direct the result to my output file - output
python parse.py >> output
However, I don't want to do this file by file manually, is there a way to take care of every single file automatically? Like
ls | awk '{print}' | python parse.py >> output
Then the problem is how could I read the file name from standardin?
or there are already some built-in functions to do the ls and those kind of work easily?
Thanks!
Os
You can list all files in the current directory using os.listdir:
import os
for filename in os.listdir(os.getcwd()):
with open(os.path.join(os.getcwd(), filename), 'r') as f: # open in readonly mode
# do your stuff
Glob
Or you can list only some files, depending on the file pattern using the glob module:
import os, glob
for filename in glob.glob('*.txt'):
with open(os.path.join(os.getcwd(), filename), 'r') as f: # open in readonly mode
# do your stuff
It doesn't have to be the current directory you can list them in any path you want:
import os, glob
path = '/some/path/to/file'
for filename in glob.glob(os.path.join(path, '*.txt')):
with open(os.path.join(os.getcwd(), filename), 'r') as f: # open in readonly mode
# do your stuff
Pipe
Or you can even use the pipe as you specified using fileinput
import fileinput
for line in fileinput.input():
# do your stuff
And you can then use it with piping:
ls -1 | python parse.py
You should try using os.walk.
import os
yourpath = 'path'
for root, dirs, files in os.walk(yourpath, topdown=False):
for name in files:
print(os.path.join(root, name))
stuff
for name in dirs:
print(os.path.join(root, name))
stuff
I was looking for this answer:
import os,glob
folder_path = '/some/path/to/file'
for filename in glob.glob(os.path.join(folder_path, '*.htm')):
with open(filename, 'r') as f:
text = f.read()
print (filename)
print (len(text))
you can choose as well '*.txt' or other ends of your filename
You can actually just use os module to do both:
list all files in a folder
sort files by file type, file name etc.
Here's a simple example:
import os #os module imported here
location = os.getcwd() # get present working directory location here
counter = 0 #keep a count of all files found
csvfiles = [] #list to store all csv files found at location
filebeginwithhello = [] # list to keep all files that begin with 'hello'
otherfiles = [] #list to keep any other file that do not match the criteria
for file in os.listdir(location):
try:
if file.endswith(".csv"):
print "csv file found:\t", file
csvfiles.append(str(file))
counter = counter+1
elif file.startswith("hello") and file.endswith(".csv"): #because some files may start with hello and also be a csv file
print "csv file found:\t", file
csvfiles.append(str(file))
counter = counter+1
elif file.startswith("hello"):
print "hello files found: \t", file
filebeginwithhello.append(file)
counter = counter+1
else:
otherfiles.append(file)
counter = counter+1
except Exception as e:
raise e
print "No files found here!"
print "Total files found:\t", counter
Now you have not only listed all the files in a folder but also have them (optionally) sorted by starting name, file type and others. Just now iterate over each list and do your stuff.
import pyautogui
import keyboard
import time
import os
import pyperclip
os.chdir("target directory")
# get the current directory
cwd=os.getcwd()
files=[]
for i in os.walk(cwd):
for j in i[2]:
files.append(os.path.abspath(j))
os.startfile("C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\Acrobat.exe")
time.sleep(1)
for i in files:
print(i)
pyperclip.copy(i)
keyboard.press('ctrl')
keyboard.press_and_release('o')
keyboard.release('ctrl')
time.sleep(1)
keyboard.press('ctrl')
keyboard.press_and_release('v')
keyboard.release('ctrl')
time.sleep(1)
keyboard.press_and_release('enter')
keyboard.press('ctrl')
keyboard.press_and_release('p')
keyboard.release('ctrl')
keyboard.press_and_release('enter')
time.sleep(3)
keyboard.press('ctrl')
keyboard.press_and_release('w')
keyboard.release('ctrl')
pyperclip.copy('')
The code below reads for any text files available in the directory which contains the script we are running. Then it opens every text file and stores the words of the text line into a list. After store the words we print each word line by line
import os, fnmatch
listOfFiles = os.listdir('.')
pattern = "*.txt"
store = []
for entry in listOfFiles:
if fnmatch.fnmatch(entry, pattern):
_fileName = open(entry,"r")
if _fileName.mode == "r":
content = _fileName.read()
contentList = content.split(" ")
for i in contentList:
if i != '\n' and i != "\r\n":
store.append(i)
for i in store:
print(i)
If you would like to open files in a directory and append them into a list, do this:
mylist=[]
for filename in os.listdir('path/here/'):
with open(os.path.join('path/here/', filename), 'r') as f:
mylist.append(f.read())
you may try another approach of using os.walk and os.path.join which is a little different from the above options:
for root, dirs, files in os.walk(EnterYourPath):
for name in files:
with open(os.path.join(root,name))as f:
text = f.read()
text variable includes all the files in the folder in the directory.