Currently I am trying to write a function will walk through the requested directory and print all the text of all the files.
Right now, the function works in displaying the file_names as a list so the files surely exist (and there is text in the files).
def PopularWordWalk (starting_dir, word_dict):
print ("In", os.path.abspath(starting_dir))
os.chdir(os.path.abspath(starting_dir))
for (this_dir,dir_names,file_names) in os.walk(starting_dir):
for file_name in file_names:
fpath = os.path.join(os.path.abspath(starting_dir), file_name)
fileobj = open(fpath, 'r')
text = fileobj.read()
print(text)
Here is my output with some checking of the directory contents:
>>> PopularWordWalk ('text_dir', word_dict)
In /Users/normanwei/Documents/Python for Programmers/Homework 4/text_dir
>>> os.listdir()
['.DS_Store', 'cats.txt', 'zen_story.txt']
the problem is that whenever i try to print the text, i get nothing. eventually I want to push the text through some other functions but as of now it seems moot without any text. Can anyone lend any experience on why no text is appearing? (when trying to open files/read/storing&printing text manually in idle it works i.e. if I just manually inputted 'cats.txt' instead of 'file_name') - currently running python 3.
EDIT - The question has been answered - just have to remove the os.chdir line - see jojo's answer for explanation.
This line won't work
file = open(file_name, 'r')
Because it would require that these files exist in the same folder you are running the script from. You would have to provide the path to those files, as well as the file names
with open(os.path.join(starting_dir,file_name), 'r') as file:
#do stuff
This way it will build the full path from the directory and the file name.
If you do os.chdir(os.path.abspath(starting_dir)) you go into starting_dir. Then for (this_dir,dir_names,file_names) in os.walk(starting_dir): will loop over nothing since starting_dir is not in starting_dir.
Long story short, comment the line os.chdir(os.path.abspath(starting_dir)) and you should be good.
Alternatively if you want to stick to the os.chdir, this should do the job:
def PopularWordWalk (starting_dir, word_dict):
print ("In", os.path.abspath(starting_dir))
os.chdir(os.path.abspath(starting_dir))
for (this_dir,dir_names,file_names) in os.walk('.'):
for file_name in file_names:
fpath = os.path.join(os.path.abspath(starting_dir), file_name)
with open(fpath, 'r') as fileobj:
text = fileobj.read()
print(text)
You'll want to join the root path with the file path. I'd change:
file = open(file_name, 'r')
to
fpath = os.path.join(this_dir, file_name)
file = open(fpath, 'r')
You may also want to use another word to describe it than file as that's a built-in function in Python. I'd recommend fileobj.
Just to add on to the previous answer, you will have to join the absolute path and the relative path of the walk.
Try this:
fpath = os.path.abspath(os.path.join(this_dir, file_name))
f = open(fpath, 'r')
Related
I want to modify several text-files within a folder.
I have the following code:
if command == "deployf":
for root, dirs, files in os.walk(all_posts, topdown = False):
for name in files:
if name.endswith(".html"):
file_name = os.path.join(root, name)
with open(file_name, 'r+') as fp:
lines = fp.readlines()
fp.seek(0)
fp.truncate()
fp.writelines(lines[:-9])
print('deployed to all files')
This deletes the last 9 lines in every html file in a folder. Now I want to merge (or append) the content of another .html file to the end of every file in the folder but I don`t know how.
You can ask for the path to the HTML file outside your loop:
path = input("Enter HTML File path to append to each file:")
Then read from the file:
root_content = open(path, 'r').readlines()
Then instead of removing the last 9 lines with fp.writelines(lines[:-9]), just write the root_content variable:
fp.writelines(root_content)
Im assuming this is what you want to do? You had all the knowledge shown in your problem to accomplish this, so please comment if i have misunderstood.
IIUC, you need to replace the last 9 lines of each (.html) with the content of your other file, right ?
If so, and to reduce visible noise, I would use Path.rglob from pathlib with slicing :
from pathlib import Path
if command == "deployf":
all_posts = Path(all_posts)
to_append = (all_posts / "the_other_file.html").read_text()
for html in all_posts.rglob("*.html"):
lines = html.read_text().splitlines()
html.write_text("\n".join(lines[:-9] + [to_append]))
print("deployed to all files")
If you need to replace a slice in the middle (e.g 5:10) of each (.html), use this :
lines = html.read_text().splitlines()
lines = lines[:4] + [to_append] + lines[10:]
html.write_text("\n".join(lines))
I have this function that is supposed to open all text files in a folder and remove all the "\n" in it.
def FormatTXT():
conhecimentos = os.listdir('U:/AutoCTE/Conhecimentos')
for x in conhecimentos:
with open(x, "r+") as f:
old = f.read()
text = old.replace("\n", "")
f.seek(0)
f.truncate(0)
f.write(text)
f.close()
But this function is returning the following error:
FileNotFoundError: [Errno 2] No such file or directory: '20200119-170415-Conhecimento de Transporte.txt'
Happens that this file actually exists in the directory and I can't figure out what I'm missing.
The file paths that you open in x are missing the prefix U:/AutoCTE/Conhecimentos. And since you are in a different directory, those relative paths will not work
def FormatTXT():
conhecimentos = os.listdir('U:/AutoCTE/Conhecimentos')
for x in conhecimentos:
with open('U:/AutoCTE/Conhecimentos/' + x, "r+") as f:
old = f.read()
text = old.replace("\n", "")
f.seek(0)
f.truncate(0)
f.write(text)
f.close()
There are better ways to do this. For example with the os.path module
I think the main problem you have is that you forgive to notice that os.listdir() return the name of the file in a directory not their path, you have to append the file name to the dir path using os.path.join()
There are several way to do this I will pick the 3 I use.
first let write a function that remove parse the file text because you get it right
, I would just recommend caution using read() in case of very large file.
def remove_end_lines(file_):
"""
remove "\n" from file
"""
with open(file_, "r+") as f:
old = f.read()
text = old.replace("\n", "")
f.seek(0)
f.truncate(0)
f.write(text)
now we have to tackle your main problem file path.
-> a choice could be to change the working dir (you should first register the original working dir in order to be able to go back to it)
def FormatTXT(my_dir):
original_dir = os.getcwd() # register original working dir
conhecimentos = os.listdir(my_dir) # liste file in the dir
os.chdir(my_dir) # change dir
for file_ in conhecimentos:
remove_end_lines(file_)
os.chdir(original_dir) # go back to original dir
second choice let's use os.path.join()
def FormatTXT(my_dir):
conhecimentos = os.listdir(my_dir) # liste all files in the dir
for file_ in conhecimentos:
file_path = os.path.join(my_dir, file_) # create the file path by appening the file name to the directory path
remove_end_lines(file_path)
In case you have subdirectory and want to perform the same operation you should use os.walk()
def FormatTXT(my_dir):
for dir_path, dir_name, files_name in os.walk(my_dir):
# files_name is a list of all file in dir_path,
if files_name: # if there is file in the current dir (the list is not empty)
for file_ in files_names:
file_path = os.path.join(my_dir, file_)
remove_end_lines(file_path)
I hope this help.
if you have more question don't hesitate to ask
My folder structure is: C:/Users/Desktop/SampleTestFiles/ProjectFiles/ExceptionLogFiles/
Using below code, I am trying to create file in ExceptionLogFiles folder if file Exceptionlog.txt does not exists and if file exists then open the file and write some text to the file. But for some reason code is unable to detect the relative path.
Please can anyone help me in correcting code:
fileDir = 'C:/Users/Desktop/SampleTestFiles'
filename = os.path.join(fileDir, '\..\ExceptionLogFiles\ExceptionLog.txt')
#print(filename) gives: C:/Users/Desktop/SampleTestFiles/../ExceptionLog.txt
if os.path.exists(filename):
print(filename, 'exists')
#Open file and write something to the file
f = open(file, 'w')
f.write("Exception Text")
f.close()
else:
print('file not exists')
#Create File and Write something to the file.
f = open(file, 'w+')
f.write("Exception Text")
f.close()
What you tried to do was kind of like this, in an addition-like fashion
(
C:/Users/Desktop/SampleTestFiles
+
.. (which is up one directory)
)
+ ExceptionLogFiles\ExceptionLog.txt
The "parenthesized" addition will actually resolve to C:/Users/Desktop/, and we add ExceptionLogFiles\ExceptionLog.txt' to that. So we'd be looking at: `C:/Users/Desktop/ExceptionLogFiles\ExceptionLog.txt'
However, even if you dropped the ..\ from your string, those backslashes don't become literal backslashes in a string without you escaping them.
Try this (and NOTE the backslashes are doubled so as to escape backslash, which is the escape character!)
fileDir = 'C:/Users/Desktop/SampleTestFiles'
filename = os.path.join(fileDir, 'ExceptionLogFiles\\ExceptionLog.txt')
Looks like you're looking for normpath
import os
fileDir = 'C:/Users/Desktop/SampleTestFiles'
filename = os.path.join(fileDir, '../ExceptionLogFiles/ExceptionLog.txt')
print(filename)
print(os.path.normpath(filename))
result:
C:/Users/Desktop/SampleTestFiles/../ExceptionLogFiles/ExceptionLog.txt
C:/Users/Desktop/ExceptionLogFiles/ExceptionLog.txt
You can use "with open('path','a+') as f", whatever file exists or not,you can write something into it.
I am trying to go to a directory and print out the content of all files in it.
for fn in os.listdir('Z:/HAR_File_Generator/HARS/job_search'):
print(fn)
When I use this code all it does is print out the file names. How can I make it so I can actually get the content of the file? I have seen a lot of ways to possibly do this but I am wondering if there is a way to do it in the same format as I have it. It doesn't make sense to me that I'm not able to get the file content instead of the name. What would make sense to me is doing fn.read() and then printing it out but that does not work.
directory = 'Z:/HAR_File_Generator/HARS/job_search'
for fn in os.listdir(directory):
print(open(os.path.join(directory, fn), 'rb').read())
Edit: You should probably close your files too but that's a separate issue.
mydir = 'Z:/HAR_File_Generator/HARS/job_search'
for fn in os.listdir(mydir):
print open(mydir+'/'+fn).readlines()
Why is your code not printing any file contents? Because you are not reading any file contents.
For printing prettily..
for fn in os.listdir(mydir):
for line in open(mydir+'/'+fn).readlines():
print line
And to avoid this closing issue in case of much much larger files,
for fn in os.listdir(mydir):
with open(mydir+'/'+fn) as fil:
print fil.readlines()
Assuming they're text files that can actually be printed:
dirpath = 'Z:/HAR_File_Generator/HARS/job_search'
for fn in os.listdir(dirpath):
with open(os.path.join(dirpath, fn), 'r') as f: # open the file
for line in f: # go through each line
print(line) # and print it
Or, in Python 3 (or Python 2 with the proper import):
dirpath = 'Z:/HAR_File_Generator/HARS/job_search'
for fn in os.listdir(dirpath):
with open(os.path.join(dirpath, fn), 'r') as f: # open the file
print(*f, sep='') # and send every line to the print function
I have a directory of text files that all have the extension .txt. My goal is to print the contents of the text file. I wish to be able use the wildcard *.txt to specify the file name I wish to open (I'm thinking along the lines of something like F:\text\*.txt?), split the lines of the text file, then print the output.
Here is an example of what I want to do, but I want to be able to change somefile when executing my command.
f = open('F:\text\somefile.txt', 'r')
for line in f:
print line,
I had checked out the glob module earlier, but I couldn't figure out how to actually do anything to the files. Here is what I came up with, not working.
filepath = "F:\irc\as\*.txt"
txt = glob.glob(filepath)
lines = string.split(txt, '\n') #AttributeError: 'list' object has no attribute 'split'
print lines
import os
import re
path = "/home/mypath"
for filename in os.listdir(path):
if re.match("text\d+.txt", filename):
with open(os.path.join(path, filename), 'r') as f:
for line in f:
print line,
Although you ignored my perfectly fine solution, here you go:
import glob
path = "/home/mydir/*.txt"
for filename in glob.glob(path):
with open(filename, 'r') as f:
for line in f:
print line,
You can use the glob module to get a list of files for wildcards:
File Wildcards
Then you just do a for-loop over this list and you are done:
filepath = "F:\irc\as\*.txt"
txt = glob.glob(filepath)
for textfile in txt:
f = open(textfile, 'r') #Maybe you need a os.joinpath here, see Uku Loskit's answer, I don't have a python interpreter at hand
for line in f:
print line,
This code accounts for both issues in the initial question: seeks for the .txt file in the current directory and then allows the user to search for some expression with the regex
#! /usr/bin/python3
# regex search.py - opens all .txt files in a folder and searches for any line
# that matches a user-supplied regular expression
import re, os
def search(regex, txt):
searchRegex = re.compile(regex, re.I)
result = searchRegex.findall(txt)
print(result)
user_search = input('Enter the regular expression\n')
path = os.getcwd()
folder = os.listdir(path)
for file in folder:
if file.endswith('.txt'):
print(os.path.join(path, file))
txtfile = open(os.path.join(path, file), 'r+')
msg = txtfile.read()
search(user_search, msg)
Check out "glob — Unix style pathname pattern expansion"
http://docs.python.org/library/glob.html
This problem just came up for me and I was able to fix it with pure python:
Link to the python docs is found here: 10.8. fnmatch — Unix filename pattern matching
Quote: "This example will print all file names in the current directory with the extension .txt:"
import fnmatch
import os
for file in os.listdir('.'):
if fnmatch.fnmatch(file, '*.txt'):
print(file)