Python 3.5:Not able to remove non alpha -numeric characters from file_name - python-3.5

i have written a python script to rename all the files present in a folder by removing all the numbers from the file name but this doesn't work .
Note :Same code works fine for python2.7
import os
def rename_files():
#(1) get file names from a folder
file_list = os.listdir(r"D:\prank")
print(file_list)
saved_path = os.getcwd()
print("Current working Directory is " + saved_path)
os.chdir(r"D:\prank")
#(2) for each file ,rename filename
for file_name in file_list:
os.rename(file_name, file_name.translate(None,"0123456789"))
rename_files()
Can anyone tell me how to make it work.Is the translate function which is not working properly

The problem is with os.rename() portion of your code.
os.rename() requires you to give it a full path to the file/folder you want to change it to, while you only gave it the file_name and not the full path.
You have to add the full path to the folders/files directory.
so it should look like this:
def rename_files():
# add the folder path
folder_path = "D:\prank\\"
file_list = os.listdir(r"D:\prank")
print(file_list)
saved_path = os.getcwd()
print("Current working Directory is " + saved_path)
os.chdir(r"D:\prank")
# Concat the folder_path with file_name to create the full path.
for file_name in file_list:
full_path = folder_path + file_name
print (full_path) # See the full path here.
os.rename(full_path, full_path.translate(None, "0123456789"))

look up the documentation for os, heres what ive found on rename:
os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
Rename the file or directory src to dst. If dst is a directory, OSError will be raised. On Unix, if dst exists and is a file, it will be replaced silently if the user has permission. The operation may fail on some Unix flavors if src and dst are on different filesystems. If successful, the renaming will be an atomic operation (this is a POSIX requirement). On Windows, if dst already exists, OSError will be raised even if it is a file.
This function can support specifying src_dir_fd and/or dst_dir_fd to supply paths relative to directory descriptors.
If you want cross-platform overwriting of the destination, use replace().
New in version 3.3: The src_dir_fd and dst_dir_fd arguments.
heres a link to the documentation, hope this helps, thanks
https://docs.python.org/3/library/os.html

Others have pointed out other issues with your code, but as to your use of translate, in Python 3.x, you need to pass a dictionary mapping ordinals to new values (or None). This code would work:
import string
...
file_name.translate(dict(ord(c), None for c in string.digits))
but this seems easier to understand:
import re
...
re.sub(r'\d', '', file_name)

Related

File not found error altough file does not exist

I am trying to read through a file using the with open () function from python. I hand in the filepath via a base path and then a relative path adding on it:
filepath = base_path + path_to_specific_file
with open (filepath) as l:
do_stuff()
base_path is using the linux home symbol ( I am using Ubuntu on a VM) ~/base_path/ since I want to have the filepath adapted on every device instead of hardcoding it.
This does not work. When I execute the code, it throws a file not found error, although the path exists. I even can open it by clicking the path in the vscode terminal.
According to this thread:
File not found from Python although file exists
the problem is the ~/ instead of /home/username/. Is there a way to replace this to have it working on every device with the correct path? I cannot comment yet on this thread since I do not have enough reputation, therefore I needed to create this new question. Sorry about that.
You can use the expanduser() from pathlib for this. Example
import pathlib
filepath = pathlib.Path(base_path) / path_to_specific_file
filepath = filepath.expanduser() # expand ~
with open(filepath) as l:
do_stuff()
This should work fine.
You can join paths e.g. with:
filepath = '/'.join((basepath, path_to_specific_file))
Or do as Kris suggested: use pathlib:
>>> basepath = Path('/tmp/')
>>> path_to_specific_file = Path('test')
>>> filepath = basepath / path_to_specific_file
>>> print(filepath)
/tmp/test
EDIT:
To access $HOME (~) you can use Path.home().

Moving a folder to itself: shutil, check if file's path is the same as the destination path, if so do nothing

I have the following code which works as expected, expect when the source file is the same as the destination file. I have tried os.path. isfile/isdir/exists but I'm hitting a wall.
So essentially this loops through the file_list and moves the file in the list to the destination. However, it can happen that the source and destination are the same, so, if the file's location is the same as the destination, then it is trying to move itself to itself and obviously fails. So in the following I need to add a check, if the file's location (source) is the same as the destination then pass.
def move_files(file_list, destination):
for file in file_list:
source_file = file
shutil.move(source_file, destination)
In this case the destination is a folder path and the source is a folder path + file name, so I need to ignore the source's file name and compare the path with the destination.
I feel I'm over complicating this, but any help is appreciated.
You can make use of abspath and dirname methods of os.path. The first one returns the absolute path of a directory, the second provides the directory name of a path.
def move_files(file_list, destination):
# just in case you don't provide absolute paths
# you can also consider using `expanduser`
destination = os.path.abspath(destination)
for file in file_list:
file_abs_path = os.path.abspath(file)
if os.path.dirname(file_abs_path) != destination:
shutil.move(file_abs_path, destination)
https://docs.python.org/3/library/os.path.html#os.path.abspath
https://docs.python.org/3/library/os.path.html#os.path.dirname
https://docs.python.org/3/library/os.path.html#os.path.expanduser
I think this is what you want
And also, i've found the source_file variable des nothing special here. So i just ignored it.
import os
import shutil
def move_files(file_list, destination):
dir_lst = os.listdir(destination)
for file in file_list:
if file not in dir_lst: # This will only move the files if its not in the destination folder
shutil.move(file, destination)
For a complete code using only os module,
import os
def move_files(file_list, destination):
dir_lst = os.listdir(destination)
for file in file_list:
if file not in dir_lst: # This will only move the files if its not in the destination folder
os.rename(file, destination)

WinError2 keeps popping up with this python 3.7.3 script to delete files in a file tree without having to scroll through them

I am REALLY (2 days) new to all of this. I am trying to delete a bunch of files in a folder in my external HD with a python 3.7.3 script but an error keeps popping up.
Firstly, this code works fine and finds the folders:
import os
for folderName, subfolders, filenames in os.walk("D:\Practice"):
for filename in filenames:
if filename.endswith('practice.docx'):
#os.unlink(filename)
print(filename)
But then when I remove the print(filename) the remove the hash, the folders can't be deleted with the following error popping up:
import os
for folderName, subfolders, filenames in os.walk("D:\Practice"):
for filename in filenames:
if filename.endswith('practice.docx'):
os.unlink(filename)
os.unlink(filename) FileNotFoundError: [WinError 2] The system cannot find the file specified: 'rootpractice.docx'
The 'rootpractice' doc is clearly recognised but won't be deleted.
Does anyone know how I can solve this? Any help for this total beginner is much appreciated.
os.unlink and similar other methods which require file paths expect either a link relative to current folder in which your script is running (which you can find out with os.getcwd() ), or the full path.
When you are iterating with os.walk, you are only passing the filename and not the full path. Try this:
import os
for folderName, subfolders, filenames in os.walk("D:\Practice"):
for filename in filenames:
if filename.endswith('practice.docx'):
full_path = os.path.join(folderName, filename)
print("About to delete the file: {}".format(full_path))
os.unlink(full_path)

Does the following program access a file in a subfolder of a folder?

using
import sys
folder = sys.argv[1]
for i in folder:
for file in i:
if file == "test.txt":
print (file)
would this access a file in the folder of a subfolder? For Example 1 main folder, with 20 subfolders, and each subfolder has 35 files. I want to pass the folder in commandline and access the first subfolder and the second file in it
Neither. This doesn't look at files or folders.
sys.argv[1] is just a string. i is the characters of that string. for file in i shouldn't work because you cannot iterate a character.
Maybe you want to glob or walk a directory instead?
Here's a short example using the os.walk method.
import os
import sys
input_path = sys.argv[1]
filters = ["test.txt"]
print(f"Searching input path '{input_path}' for matches in {filters}...")
for root, dirs, files in os.walk(input_path):
for file in files:
if file in filters:
print("Found a match!")
match_path = os.path.join(root, file)
print(f"The path is: {match_path}")
If the above file was named file_finder.py, and you wanted to search the directory my_folder, you would call python file_finder.py my_folder from the command line. Note that if my_folder is not in the same directory as file_finder.py, then you have to provide the full path.
No, this won't work, because folder will be a string, so you'll be iterating through the characters of the string. You could use the os module (e.g., the os.listdir() method). I don't know what exactly are you passing to the script, but probably it would be easiest by passing an absolute path. Look at some other methods in the module used for path manipulation.

create a list of files to be deleted

I am working on a search-and-destroy type program which I need it to do is search all directories with a certain file-name and append them to a list. after that delete all those files...not objects in list or the list...
import os
file_list=[]
for root, dirs, files in os.walk(path-to-dir'):
for f_name in files:
if f_name.startswith("file-name"):
file_list.append(f_name)
I could write up to appending part of the code but I don't know next...
Some help please
To remove a file from your computer, use os.remove(). It takes full path to the file as it's parameter, so instead of calling os.remove("infectedFile.dll") you would call os.remove("C:/program files/avira/infectedFile.dll")
So your file_list should contain full paths to the files, and then just call:
for file in file_list:
os.remove(file)
Modify your file_list.append(f_name). The f_name is only a bare name. You need to add the path to the file name in the time of processing, because you do not know where the file was found in the directory hierarchy:
file_list.append(os.path.join(root, f_name))
The root variable contains the path during walking.
To make check whether your code works, just print the content of the list:
print('\n'.join(file_list))
Or you can do it in the loop to get ready for the later part:
for fname in file_list:
print(fname)
Then you just add the os.remove(fname) to remove the file name:
for fname in file_list:
print('removing', fname)
os.remove(fname)

Resources