I want to replace a single character on a bunch of file names with another character. However, when I want to replace files with /
to another character, it doesn't work. It does work with other characters I want to replace, such as -
.
The python file is on the directory path, and I 'cd' to the directory path to run the program.
I expect that every /
on a file name would be replaced with a _
. Like this: file/1.txt
to file_1.txt
.
However, the files stay the same. Like this: file/1.txt
to file/1.txt
.
I use this code:
# Replace a character of a name file with another charater
from importlib.metadata import files
import os
counter = 0
path = r"/Users/user/test"
char = input('Enter character or string you want to replace:')
repl = input('Enter character or string you want this to be replaced with:')
files = []
# Loop, doesn't work with "/" for some reason
for file_name in os.listdir(path):
if char in file_name :
old_name = file_name
new_name = file_name.replace(char, repl)
counter = 1
files.append(new_name)
os.rename(old_name, new_name)
print(counter)
print(files)
print("Done! Check your files")
As an alternative, I deleted the variables char
and repl
and instead used this in the for
loop, but it still doesn't work:
for file_name in os.listdir(path):
if "/" in file_name :
old_name = file_name
new_name = file_name.replace("/", "_")
counter = 1
CodePudding user response:
I'd use pathlib
which is much more clean and convenient that using os module.
from pathlib import Path
base_folder = Path(r"/Users/user/test")
old_names = [f for f in base_folder.glob('*') if f.is_file()]
new_names = [f'{f.parts[-2]}_{f.name}' for f in old_names]
for o_name, n_name in zip(old_names, new_names):
o_name.with_name(n_name)
You first create a list of file paths for all the files in the folder.
Then the second list comprehension goes through a list of files and for each file grabs its parent folder name and the file name and combines them in an f-string with _ in between.
Now, finally you go through the old and new file names and assign a new name to each of the original files.
EDIT:
If you want to exclude hidden files you need to amend the first comprehension to exclude files that start with a .
:
old_names = [f for f in base_folder.glob('*.txt')
if not any(part.startswith('.') for part in f.parts) and f.is_file()]
CodePudding user response:
I managed to solve it with this.
# Replace a character of a file with another charater
from importlib.metadata import files
import os
counter = 0
path=input("Enter path: ")
char=input('Enter character or string you want to replace:')
repl=input('Enter character or string you want this to be replaced with:')
files=[]
# Ignore hidden files
def listdir_nohidden(path):
for f in os.listdir(path):
if not f.startswith('.'):
yield f
# Loop, instead of "/" use ":"
for file_name in listdir_nohidden(path):
if char in file_name :
old_name=file_name
new_name=file_name.replace(char,repl)
counter =1
files.append(new_name)
os.rename(old_name,new_name)
print(counter)
print(files)
print("Done! Check your files")
Files change like this: test/1.txt
--> test_1.txt
The problem was that for some reason, when I debug with print(file_name)
, files with "/" show ":" instead. The other problem, were the hidden files, which I solved above.