How remove all whitespace in multiple filenames? - python

I'm new to Python. I am converting evtx log files to xml, however, some of the evtx files have whitespace in their names and I get an error when the file conversion starts. One of the solutions is to manually remove all the whitespace from the evtx file names, but this is impossible when you deal with a large number of files.
I need to remove all the whitespace from file names in multiple directories. I am trying to rename the files by removing the whitespace with .replace(" ",""), however, I keep getting an error:
FileNotFoundError: [Errno 2] No such file or directory:
Code:
dir_path = '/home/user/evtx_logs'
for dirpath, dirnames, filenames in os.walk(dir_path):
for f in filenames:
new_filename = f.replace(" ","")
os.rename(f,new_filename)
Is there any other alternative to rename or perhaps to ignore the white space in a file name?

Try printing out the values of your directory walk. You will notice that the filenames are not paths, they are just the names of the files. When you try to rename the file, you need to point your function to the entire path. Something like this:
for dirpath, dirnames, filenames in os.walk(dir_path):
for f in filenames:
filepath = os.path.join(dirpath, f)
new_filename = f.replace(" ","")
new_filepath = os.path.join(dirpath, new_filename)
os.rename(filepath, new_filepath)

solution
dir_path = '/home/user/evtx_logs'
for dirpath, dirnames, filenames in os.walk(dir_path):
for f in filenames:
new_filename = f.replace(" ","")
os.rename(os.path.join(dirpath, f), os.path.join(dirpath, new_filename))
you need to provide full path to os.rename in order to work the renaming.
here
os.path.join(dirpath, new_filename)
dirpath or dirnames, dont know exactly:
os.path.join(dirnames, new_filename)

Related

Moving only one file of each sub directories to new sub directories

I have question regarding moving one file in each sub directories to other new sub directories. So for example if I have directory as it shown in the image
And from that, I want to pick only the first file in each sub directories then move it to another new sub directories with the same name as you can see from the image. And this is my expected result
I have tried using os.walk to select the first file of each sub directories, but I still don't know how to move it to another sub directories with the same name
path = './test/'
new_path = './x/'
n = 1
fext = ".png"
for dirpath, dirnames, filenames in os.walk(path):
for filename in [f for f in filenames if f.endswith(fext)][:n]:
print(filename) #this only print the file name in each sub dir
The expected result can be seen in the image above
You are almost there :)
All you need is to have both full path of file: an old path (existing file) and a new path (where you want to move it).
As it mentioned in this post you can move files in different ways in Python. You can use "os.rename" or "shutil.move".
Here is a full tested code-sample:
import os, shutil
path = './test/'
new_path = './x/'
n = 1
fext = ".png"
for dirpath, dirnames, filenames in os.walk(path):
for filename in [f for f in filenames if f.endswith(fext)][:n]:
print(filename) #this only print the file name in each sub dir
filenameFull = os.path.join(dirpath, filename)
new_filenameFull = os.path.join(new_path, filename)
# if new directory doesn't exist - you create it recursively
if not os.path.exists(new_path):
os.makedirs(new_path)
# Use "os.rename"
#os.rename(filenameFull, new_filenameFull)
# or use "shutil.move"
shutil.move(filenameFull, new_filenameFull)

write filenames of different extention into different text files

import os
exts = ['ppt', 'pptx', 'doc', 'docx', 'txt', 'pdf', 'epub']
files = []
for root, dirnames, filenames in os.walk('.'):
for i in exts:
for file in filenames:
if file.endswith(i):
file1 = os.path.join(root, file)
print(file1)
with open(os.getcwd()+ r"\ally_"+i+".txt", 'w+') as f:
f.write("%s\n" % file1)
I m trying this code. How do I write all files in my system with ex. doc extention into a file named all_docs.txt in my desktop? file.write() inside for loop only write the last line of each extention into the files.
You need to open the log file in append mode (a) and not in write mode (w), because with w the file gets truncated (all content deleted) before anything new is written to it.
You can look into the docs of open(). This answer also has an overview of all the file modes.
Does it work with a for you?
with open(os.getcwd()+ r"\ally_"+i+".txt", 'w+') as f:
f.write("%s\n" % file1)
According to https://docs.python.org/2/library/functions.html#open the "w+" operation truncates the file.
Modes 'r+', 'w+' and 'a+' open the file for updating (reading and writing); note that 'w+' truncates the file.
The mode w+ for open causes to truncate the file, this is the reason for losing the lines, and only the last one will stay there.
An other little problem can be that this method of joining the path and the file name is not portable. You should user os.path.join for that purpose.
with open(os.path.join(os.getcwd(),"ally_"+i+".txt"), 'a') as f:
f.write("%s\n" % file1)
An other issue can be the week performance which you can have in case of many directories and files.
In your code you run through the filenames in the directory for each extension and open the output file again and again.
One more issue can be the checking of the extension. In most cases the extension can be determined by checking the ending of the file name, but sometimes it can be misleading. E.g. '.doc' is an extension however in a filename 'Medoc' the ending 'doc' is just 3 letters in a name.
So I give an example solution for these problems:
import os
exts = ['ppt', 'pptx', 'doc', 'docx', 'txt', 'pdf', 'epub']
files = []
outfiles = {}
for root, dirnames, filenames in os.walk('.'):
for filename in filenames:
_, ext = os.path.splitext(filename)
ext = ext[1:] # we do not need "."
if ext in exts:
file1 = os.path.join(root, filename)
#print(i,file1)
if ext not in outfiles:
outfiles[ext] = open(os.path.join(os.getcwd(),"ally_"+ext+".txt"), 'a')
outfiles[ext].write("%s\n" % file1)
for ext,file in outfiles.iteritems():
file.close()

Rename Files without Extension

So I got a Directory Dir and in Dir there are three subdirectories with five Files each:
Dir/A/ one,two,three,four,five.txt
Dir/B/ one,two,three,four,five.txt
Dir/C/ one,two,three,four,five.txt
As you can see there are four Files without extension and one with the .txtextension
How do I rename all Files without extension in a recursive manner?
Currently I'm trying this, which works for a single Directory, but how could I catch all Files if I put this Script into Dir?
import os, sys
for filename in os.listdir(os.path.dirname(os.path.abspath(__file__))):
base_file, ext = os.path.splitext(filename)
if ext == "":
os.rename(filename, base_file + ".png")
Use os.walk if you want to perform recursive traversal.
for root, dirs, files in os.walk(os.path.dirname(os.path.abspath(__file__))):
for file in files:
base_path, ext = os.path.splitext(os.path.join(root, file))
if not ext:
os.rename(base_path, base_path + ".png")
os.walk will segregate your files into normal files and directories, so os.path.isdir is not needed.
import os
my_dir = os.getcwd()
for root, dirnames, fnames in os.walk(my_dir):
for fname in fnames:
if fname.count('.'): continue # don't process a file with an extension
os.rename(os.path.join(root, fname), os.path.join(root, "{}.png".format(fname)))

Unzipping and renaming files/folders

Kind of new to python. But after searching and trying to unzip some folders, then rename them that don't have static names. For example the file is New_05222016. The #s are the date, and that always changes. I want it to be a unzipped folder that is labeled "New".
This is what i have so far. It will unzipp my file, but won't rename it.
import zipfile,fnmatch,os
rootPath = r"C:/Users/Bob/Desktop/Bill"
pattern = '*.zip'
New = 'New*'
for root, dirs, files in os.walk(rootPath):
for filename in fnmatch.filter(files, pattern):
print(os.path.join(root, filename))
zipfile.ZipFile(os.path.join(root, filename)).extractall(os.path.join(root, os.path.splitext(filename)[0]))
for root, dirs, files in os.walk(rootPath):
for filename in fnmatch.filter(dir,New):
os.rename(dir,'C:/Users/Bob/Desktop/Bill/New')
if tried other ways. Such as just os.rename and typing it out. But i'm at a loss of what to do.
os.rename() will work fine, just be sure to specify the full path.
I've modified your example using os.listdir() to store the name of the unzipped directory and then renamed it using os.rename(). I also used re to leave the name of the zipped file intact.
import zipfile,fnmatch,os, re
rootPath = r"C:\Users\Bob\Desktop\Bill"
pattern = '*.zip'
New = 'New*'
for root, dirs, files in os.walk(rootPath):
for filename in fnmatch.filter(files, pattern):
print(os.path.join(root, filename))
zipfile.ZipFile(os.path.join(root, filename)).extractall(os.path.join(root, os.path.splitext(filename)[0]))
for dirName in os.listdir(rootPath):
if not re.search("zip", dirName):
os.rename(os.path.join(rootPath, dirName), os.path.join(rootPath,"New"))
I hope this helps!

directory listing in python

I am getting trouble with directory listing.Suppose, I have a directory with some subdirectory(named as a-z, 0-9, %, -).In each subdirectory, I have some related xml files.
So, I have to read each lines of this files.I have tried with the following code.
def listFilesMain(dirpath):
for dirname, dirnames, filenames in os.walk(dirpath):
for subdirname in dirnames:
os.path.join(dirname, subdirname)
for filename in filenames:
fPath = os.path.join(dirname, filename)
fileListMain.append(fPath)
It works only if I tried to run my program from subdirectory, but no results if I tried to run from main directory. What's going wrong here?
Any kind of help will be greatly appreciated. Thanks!
How about this:
def list_files(dirpath):
files = []
for dirname, dirnames, filenames in os.walk(dirpath):
files += [os.path.join(dirname, filename) for filename in filenames]
return files
You could also do this as a generator, so the list isn't stored in its entirety:
def list_files(dirpath):
for dirname, dirnames, filenames in os.walk(dirpath):
for filename in filenames:
yield os.path.join(dirname, filename)
Finally, you might want to enforce absolute paths:
def list_files(dirpath):
dirpath = os.path.abspath(dirpath)
for dirname, dirnames, filenames in os.walk(dirpath):
for filename in filenames:
yield os.path.join(dirname, filename)
All of these can be called with a line like:
for filePath in list_files(dirpath):
# Check that the file is an XML file.
# Then handle the file.
if your subdirectories are softlinks, make sure you specify followlinks=True as an argument to os.walk(..). From the documentation:
By default, os.walk does not follow symbolic links to subdirectories on
systems that support them. In order to get this functionality, set the
optional argument 'followlinks' to true.

Categories