Renaming all files/folders in first children folders but not sub-children
Let's say I have this folder tree:
├──FolderParent
├── FolderA
├── FolderAA_IMG -- should be renamed
├── file_IMG_AA1.txt -- should NOT be renamed
├── file_VID_AA1.txt -- should NOT be renamed
├── file_IMG_A1.txt -- should be renamed
├── file_PANO_A1.txt -- should be renamed
├── FolderB
├── file_IMG_B1.txt -- should be renamed
├── file_PANO_B1.txt -- should be renamed
As you can see, only the files/folders in the first children folder should be renamed, not the other ones. I follow this base code and then I added a second loop above but I wonder if the double for
loop is the right way to go.
import os
# custom var
path= r"C:UsersuserFolderParent"
# other cvar
number_modified_files= 0
# get all path of subfolder
all_subfolders = [f.path for f in os.scandir(path) if f.is_dir() ]
print(all_subfolders)
for folder in all_subfolders:
# set the path to the folder: otherwise the rename file won't work
os.chdir(folder)
#won't rename files in subfolder but will rename folder in the path
for filename in os.listdir(folder):
print("new file:", filename)
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
print(f"End : {number_modified_file} files renamed")
python file-system
add a comment |
Let's say I have this folder tree:
├──FolderParent
├── FolderA
├── FolderAA_IMG -- should be renamed
├── file_IMG_AA1.txt -- should NOT be renamed
├── file_VID_AA1.txt -- should NOT be renamed
├── file_IMG_A1.txt -- should be renamed
├── file_PANO_A1.txt -- should be renamed
├── FolderB
├── file_IMG_B1.txt -- should be renamed
├── file_PANO_B1.txt -- should be renamed
As you can see, only the files/folders in the first children folder should be renamed, not the other ones. I follow this base code and then I added a second loop above but I wonder if the double for
loop is the right way to go.
import os
# custom var
path= r"C:UsersuserFolderParent"
# other cvar
number_modified_files= 0
# get all path of subfolder
all_subfolders = [f.path for f in os.scandir(path) if f.is_dir() ]
print(all_subfolders)
for folder in all_subfolders:
# set the path to the folder: otherwise the rename file won't work
os.chdir(folder)
#won't rename files in subfolder but will rename folder in the path
for filename in os.listdir(folder):
print("new file:", filename)
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
print(f"End : {number_modified_file} files renamed")
python file-system
add a comment |
Let's say I have this folder tree:
├──FolderParent
├── FolderA
├── FolderAA_IMG -- should be renamed
├── file_IMG_AA1.txt -- should NOT be renamed
├── file_VID_AA1.txt -- should NOT be renamed
├── file_IMG_A1.txt -- should be renamed
├── file_PANO_A1.txt -- should be renamed
├── FolderB
├── file_IMG_B1.txt -- should be renamed
├── file_PANO_B1.txt -- should be renamed
As you can see, only the files/folders in the first children folder should be renamed, not the other ones. I follow this base code and then I added a second loop above but I wonder if the double for
loop is the right way to go.
import os
# custom var
path= r"C:UsersuserFolderParent"
# other cvar
number_modified_files= 0
# get all path of subfolder
all_subfolders = [f.path for f in os.scandir(path) if f.is_dir() ]
print(all_subfolders)
for folder in all_subfolders:
# set the path to the folder: otherwise the rename file won't work
os.chdir(folder)
#won't rename files in subfolder but will rename folder in the path
for filename in os.listdir(folder):
print("new file:", filename)
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
print(f"End : {number_modified_file} files renamed")
python file-system
Let's say I have this folder tree:
├──FolderParent
├── FolderA
├── FolderAA_IMG -- should be renamed
├── file_IMG_AA1.txt -- should NOT be renamed
├── file_VID_AA1.txt -- should NOT be renamed
├── file_IMG_A1.txt -- should be renamed
├── file_PANO_A1.txt -- should be renamed
├── FolderB
├── file_IMG_B1.txt -- should be renamed
├── file_PANO_B1.txt -- should be renamed
As you can see, only the files/folders in the first children folder should be renamed, not the other ones. I follow this base code and then I added a second loop above but I wonder if the double for
loop is the right way to go.
import os
# custom var
path= r"C:UsersuserFolderParent"
# other cvar
number_modified_files= 0
# get all path of subfolder
all_subfolders = [f.path for f in os.scandir(path) if f.is_dir() ]
print(all_subfolders)
for folder in all_subfolders:
# set the path to the folder: otherwise the rename file won't work
os.chdir(folder)
#won't rename files in subfolder but will rename folder in the path
for filename in os.listdir(folder):
print("new file:", filename)
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
print(f"End : {number_modified_file} files renamed")
python file-system
python file-system
edited 3 hours ago
Jamal♦
30.3k11116226
30.3k11116226
asked yesterday
MagTun
1354
1354
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
You should rethink your solution in terms of regexes:
#!/usr/bin/env python3
import re
from os import scandir, rename, path
def rename_children(parent):
n_renamed = 0
re_fname = re.compile('(IMG|PANO|VID)_')
for child_dir in scandir(parent):
if child_dir.is_dir():
for child in scandir(child_dir):
renamed = re_fname.sub('', child.name)
if renamed != child.name:
new_path = path.join(child_dir.path, renamed)
print(f'Renaming {child.path} to {new_path}')
rename(child.path, new_path)
n_renamed += 1
print(f'{n_renamed} files renamed')
Note the following changes:
- Only one
if
to check whether the regex matches - Use
scandir
instead oflistdir
- Do not call
chdir
; there's no point - Don't call
replace
; the pattern check and the replacement operation can be combined by usingsub
- Don't store a list of
all_subfolders
; simply iterate over the results
add a comment |
Use regex to replace pattern in filename
The structure of these if else
all similar, you can use re
to simplify it.
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
So you are looking for IMG_
, PANO_
and VID_
in filename and try to replace it delete this part.
Instead of using os.rename
multiply times, we can use re.sub(pattern, repl, string, count=0, flags=0)
to do this.
It will Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl.
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
The pattern
meaning match one in three. I am not sure if your are familiar with regex, here is the doc.
And if the renamed_filename not equal filename it is modified, so whole part will be
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
if renamed_filename != filename:
number_modified_files +=1
os.rename(filename, renamed_filename)
Edit: Incorrect to use re.sub with os.rename
To fix this just remove the os.chdir(folder)
, there is no point doing this
# os.chdir(folder)
...
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
file_path = os.path.join(folder, filename)
if renamed_filename != filename:
number_modified_files +=1
renamed_file_path = os.path.join(folder, renamed_filename)
os.rename(file_path, renamed_file_path)
Regex side effect
But the regex code will work differ from your original code, as in your code, the replace end if it match in one pattern, but regex solution will try to replace all patterns in IMG_
PANO_
and VID_
.
Store replace pattern in list
I suggest you use a list to store the patterns(IMG_
PANO_
and VID_
)
if you wanna stop replace in the first match, use a loop to check one by one,
patterns = ["IMG_", "PANO_", "VID_"]
...
for pattern in patterns:
if pattern in filename:
os.rename(filename, filename.replace(pattern, ''))
number_modified_files +=1
Or if you wanna replace all patterns, use regex
re.compile("|".join(patterns))
It is easy for only 3 patterns now, but will drive you crazy if there are 30.
There's no point to passing thecount
andflags
kwargs tore.sub
in this case.
– Reinderien
yesterday
Also, don't use there.sub
form at all. Usere.compile
and callsub
on the compiled regex object.
– Reinderien
yesterday
Finally: you're applyingrename
andsub
on the same filename, which is incorrect.sub
must only be applied on the filename without path, andrename
must have the path.
– Reinderien
yesterday
you are correct for "sub must only be applied on the filename without path", I took a mistake on it, and "There's no point to passing the count and flags kwargs to re.sub in this case. " I just showing the function, and thanks for " Use re.compile and call sub on the compiled regex object.", updating my comment
– Aries_is_there
yesterday
Looks OK now :)
– Reinderien
yesterday
add a comment |
You should use a recursive function like this:
import os
def rename_files(basedir):
for f in os.listdir(basedir):
if os.path.isdir(f):
rename_files(os.path.join(basedir, f))
else:
if "IMG_" in f:
os.rename(f, f.replace('IMG_', ''))
else:
pass
rename_files('C:/Users/user/FolderParent')
else; pass
has no effect; you can delete it and merge yourelse if
into anelif
.
– Reinderien
yesterday
Also, your path is wrong, because you have backslashes that will be interpreted as escapes. Use a raw string or use forward slashes.
– Reinderien
yesterday
Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance thanlistdir
.
– Reinderien
yesterday
1
Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
– Reinderien
yesterday
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210481%2frenaming-all-files-folders-in-first-children-folders-but-not-sub-children%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You should rethink your solution in terms of regexes:
#!/usr/bin/env python3
import re
from os import scandir, rename, path
def rename_children(parent):
n_renamed = 0
re_fname = re.compile('(IMG|PANO|VID)_')
for child_dir in scandir(parent):
if child_dir.is_dir():
for child in scandir(child_dir):
renamed = re_fname.sub('', child.name)
if renamed != child.name:
new_path = path.join(child_dir.path, renamed)
print(f'Renaming {child.path} to {new_path}')
rename(child.path, new_path)
n_renamed += 1
print(f'{n_renamed} files renamed')
Note the following changes:
- Only one
if
to check whether the regex matches - Use
scandir
instead oflistdir
- Do not call
chdir
; there's no point - Don't call
replace
; the pattern check and the replacement operation can be combined by usingsub
- Don't store a list of
all_subfolders
; simply iterate over the results
add a comment |
You should rethink your solution in terms of regexes:
#!/usr/bin/env python3
import re
from os import scandir, rename, path
def rename_children(parent):
n_renamed = 0
re_fname = re.compile('(IMG|PANO|VID)_')
for child_dir in scandir(parent):
if child_dir.is_dir():
for child in scandir(child_dir):
renamed = re_fname.sub('', child.name)
if renamed != child.name:
new_path = path.join(child_dir.path, renamed)
print(f'Renaming {child.path} to {new_path}')
rename(child.path, new_path)
n_renamed += 1
print(f'{n_renamed} files renamed')
Note the following changes:
- Only one
if
to check whether the regex matches - Use
scandir
instead oflistdir
- Do not call
chdir
; there's no point - Don't call
replace
; the pattern check and the replacement operation can be combined by usingsub
- Don't store a list of
all_subfolders
; simply iterate over the results
add a comment |
You should rethink your solution in terms of regexes:
#!/usr/bin/env python3
import re
from os import scandir, rename, path
def rename_children(parent):
n_renamed = 0
re_fname = re.compile('(IMG|PANO|VID)_')
for child_dir in scandir(parent):
if child_dir.is_dir():
for child in scandir(child_dir):
renamed = re_fname.sub('', child.name)
if renamed != child.name:
new_path = path.join(child_dir.path, renamed)
print(f'Renaming {child.path} to {new_path}')
rename(child.path, new_path)
n_renamed += 1
print(f'{n_renamed} files renamed')
Note the following changes:
- Only one
if
to check whether the regex matches - Use
scandir
instead oflistdir
- Do not call
chdir
; there's no point - Don't call
replace
; the pattern check and the replacement operation can be combined by usingsub
- Don't store a list of
all_subfolders
; simply iterate over the results
You should rethink your solution in terms of regexes:
#!/usr/bin/env python3
import re
from os import scandir, rename, path
def rename_children(parent):
n_renamed = 0
re_fname = re.compile('(IMG|PANO|VID)_')
for child_dir in scandir(parent):
if child_dir.is_dir():
for child in scandir(child_dir):
renamed = re_fname.sub('', child.name)
if renamed != child.name:
new_path = path.join(child_dir.path, renamed)
print(f'Renaming {child.path} to {new_path}')
rename(child.path, new_path)
n_renamed += 1
print(f'{n_renamed} files renamed')
Note the following changes:
- Only one
if
to check whether the regex matches - Use
scandir
instead oflistdir
- Do not call
chdir
; there's no point - Don't call
replace
; the pattern check and the replacement operation can be combined by usingsub
- Don't store a list of
all_subfolders
; simply iterate over the results
answered yesterday
Reinderien
3,160720
3,160720
add a comment |
add a comment |
Use regex to replace pattern in filename
The structure of these if else
all similar, you can use re
to simplify it.
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
So you are looking for IMG_
, PANO_
and VID_
in filename and try to replace it delete this part.
Instead of using os.rename
multiply times, we can use re.sub(pattern, repl, string, count=0, flags=0)
to do this.
It will Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl.
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
The pattern
meaning match one in three. I am not sure if your are familiar with regex, here is the doc.
And if the renamed_filename not equal filename it is modified, so whole part will be
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
if renamed_filename != filename:
number_modified_files +=1
os.rename(filename, renamed_filename)
Edit: Incorrect to use re.sub with os.rename
To fix this just remove the os.chdir(folder)
, there is no point doing this
# os.chdir(folder)
...
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
file_path = os.path.join(folder, filename)
if renamed_filename != filename:
number_modified_files +=1
renamed_file_path = os.path.join(folder, renamed_filename)
os.rename(file_path, renamed_file_path)
Regex side effect
But the regex code will work differ from your original code, as in your code, the replace end if it match in one pattern, but regex solution will try to replace all patterns in IMG_
PANO_
and VID_
.
Store replace pattern in list
I suggest you use a list to store the patterns(IMG_
PANO_
and VID_
)
if you wanna stop replace in the first match, use a loop to check one by one,
patterns = ["IMG_", "PANO_", "VID_"]
...
for pattern in patterns:
if pattern in filename:
os.rename(filename, filename.replace(pattern, ''))
number_modified_files +=1
Or if you wanna replace all patterns, use regex
re.compile("|".join(patterns))
It is easy for only 3 patterns now, but will drive you crazy if there are 30.
There's no point to passing thecount
andflags
kwargs tore.sub
in this case.
– Reinderien
yesterday
Also, don't use there.sub
form at all. Usere.compile
and callsub
on the compiled regex object.
– Reinderien
yesterday
Finally: you're applyingrename
andsub
on the same filename, which is incorrect.sub
must only be applied on the filename without path, andrename
must have the path.
– Reinderien
yesterday
you are correct for "sub must only be applied on the filename without path", I took a mistake on it, and "There's no point to passing the count and flags kwargs to re.sub in this case. " I just showing the function, and thanks for " Use re.compile and call sub on the compiled regex object.", updating my comment
– Aries_is_there
yesterday
Looks OK now :)
– Reinderien
yesterday
add a comment |
Use regex to replace pattern in filename
The structure of these if else
all similar, you can use re
to simplify it.
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
So you are looking for IMG_
, PANO_
and VID_
in filename and try to replace it delete this part.
Instead of using os.rename
multiply times, we can use re.sub(pattern, repl, string, count=0, flags=0)
to do this.
It will Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl.
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
The pattern
meaning match one in three. I am not sure if your are familiar with regex, here is the doc.
And if the renamed_filename not equal filename it is modified, so whole part will be
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
if renamed_filename != filename:
number_modified_files +=1
os.rename(filename, renamed_filename)
Edit: Incorrect to use re.sub with os.rename
To fix this just remove the os.chdir(folder)
, there is no point doing this
# os.chdir(folder)
...
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
file_path = os.path.join(folder, filename)
if renamed_filename != filename:
number_modified_files +=1
renamed_file_path = os.path.join(folder, renamed_filename)
os.rename(file_path, renamed_file_path)
Regex side effect
But the regex code will work differ from your original code, as in your code, the replace end if it match in one pattern, but regex solution will try to replace all patterns in IMG_
PANO_
and VID_
.
Store replace pattern in list
I suggest you use a list to store the patterns(IMG_
PANO_
and VID_
)
if you wanna stop replace in the first match, use a loop to check one by one,
patterns = ["IMG_", "PANO_", "VID_"]
...
for pattern in patterns:
if pattern in filename:
os.rename(filename, filename.replace(pattern, ''))
number_modified_files +=1
Or if you wanna replace all patterns, use regex
re.compile("|".join(patterns))
It is easy for only 3 patterns now, but will drive you crazy if there are 30.
There's no point to passing thecount
andflags
kwargs tore.sub
in this case.
– Reinderien
yesterday
Also, don't use there.sub
form at all. Usere.compile
and callsub
on the compiled regex object.
– Reinderien
yesterday
Finally: you're applyingrename
andsub
on the same filename, which is incorrect.sub
must only be applied on the filename without path, andrename
must have the path.
– Reinderien
yesterday
you are correct for "sub must only be applied on the filename without path", I took a mistake on it, and "There's no point to passing the count and flags kwargs to re.sub in this case. " I just showing the function, and thanks for " Use re.compile and call sub on the compiled regex object.", updating my comment
– Aries_is_there
yesterday
Looks OK now :)
– Reinderien
yesterday
add a comment |
Use regex to replace pattern in filename
The structure of these if else
all similar, you can use re
to simplify it.
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
So you are looking for IMG_
, PANO_
and VID_
in filename and try to replace it delete this part.
Instead of using os.rename
multiply times, we can use re.sub(pattern, repl, string, count=0, flags=0)
to do this.
It will Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl.
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
The pattern
meaning match one in three. I am not sure if your are familiar with regex, here is the doc.
And if the renamed_filename not equal filename it is modified, so whole part will be
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
if renamed_filename != filename:
number_modified_files +=1
os.rename(filename, renamed_filename)
Edit: Incorrect to use re.sub with os.rename
To fix this just remove the os.chdir(folder)
, there is no point doing this
# os.chdir(folder)
...
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
file_path = os.path.join(folder, filename)
if renamed_filename != filename:
number_modified_files +=1
renamed_file_path = os.path.join(folder, renamed_filename)
os.rename(file_path, renamed_file_path)
Regex side effect
But the regex code will work differ from your original code, as in your code, the replace end if it match in one pattern, but regex solution will try to replace all patterns in IMG_
PANO_
and VID_
.
Store replace pattern in list
I suggest you use a list to store the patterns(IMG_
PANO_
and VID_
)
if you wanna stop replace in the first match, use a loop to check one by one,
patterns = ["IMG_", "PANO_", "VID_"]
...
for pattern in patterns:
if pattern in filename:
os.rename(filename, filename.replace(pattern, ''))
number_modified_files +=1
Or if you wanna replace all patterns, use regex
re.compile("|".join(patterns))
It is easy for only 3 patterns now, but will drive you crazy if there are 30.
Use regex to replace pattern in filename
The structure of these if else
all similar, you can use re
to simplify it.
if "IMG_" in filename:
os.rename(filename, filename.replace('IMG_', ''))
number_modified_files +=1
elif "PANO_" in filename:
os.rename(filename, filename.replace('PANO_', ''))
number_modified_files +=1
elif "VID_" in filename:
os.rename(filename, filename.replace('VID_', ''))
number_modified_files +=1
So you are looking for IMG_
, PANO_
and VID_
in filename and try to replace it delete this part.
Instead of using os.rename
multiply times, we can use re.sub(pattern, repl, string, count=0, flags=0)
to do this.
It will Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl.
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
The pattern
meaning match one in three. I am not sure if your are familiar with regex, here is the doc.
And if the renamed_filename not equal filename it is modified, so whole part will be
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
if renamed_filename != filename:
number_modified_files +=1
os.rename(filename, renamed_filename)
Edit: Incorrect to use re.sub with os.rename
To fix this just remove the os.chdir(folder)
, there is no point doing this
# os.chdir(folder)
...
pattern = 'IMG_|PANO_|VID_'
renamed_filename = re.sub(pattern, '', filename)
file_path = os.path.join(folder, filename)
if renamed_filename != filename:
number_modified_files +=1
renamed_file_path = os.path.join(folder, renamed_filename)
os.rename(file_path, renamed_file_path)
Regex side effect
But the regex code will work differ from your original code, as in your code, the replace end if it match in one pattern, but regex solution will try to replace all patterns in IMG_
PANO_
and VID_
.
Store replace pattern in list
I suggest you use a list to store the patterns(IMG_
PANO_
and VID_
)
if you wanna stop replace in the first match, use a loop to check one by one,
patterns = ["IMG_", "PANO_", "VID_"]
...
for pattern in patterns:
if pattern in filename:
os.rename(filename, filename.replace(pattern, ''))
number_modified_files +=1
Or if you wanna replace all patterns, use regex
re.compile("|".join(patterns))
It is easy for only 3 patterns now, but will drive you crazy if there are 30.
edited yesterday
answered yesterday
Aries_is_there
687211
687211
There's no point to passing thecount
andflags
kwargs tore.sub
in this case.
– Reinderien
yesterday
Also, don't use there.sub
form at all. Usere.compile
and callsub
on the compiled regex object.
– Reinderien
yesterday
Finally: you're applyingrename
andsub
on the same filename, which is incorrect.sub
must only be applied on the filename without path, andrename
must have the path.
– Reinderien
yesterday
you are correct for "sub must only be applied on the filename without path", I took a mistake on it, and "There's no point to passing the count and flags kwargs to re.sub in this case. " I just showing the function, and thanks for " Use re.compile and call sub on the compiled regex object.", updating my comment
– Aries_is_there
yesterday
Looks OK now :)
– Reinderien
yesterday
add a comment |
There's no point to passing thecount
andflags
kwargs tore.sub
in this case.
– Reinderien
yesterday
Also, don't use there.sub
form at all. Usere.compile
and callsub
on the compiled regex object.
– Reinderien
yesterday
Finally: you're applyingrename
andsub
on the same filename, which is incorrect.sub
must only be applied on the filename without path, andrename
must have the path.
– Reinderien
yesterday
you are correct for "sub must only be applied on the filename without path", I took a mistake on it, and "There's no point to passing the count and flags kwargs to re.sub in this case. " I just showing the function, and thanks for " Use re.compile and call sub on the compiled regex object.", updating my comment
– Aries_is_there
yesterday
Looks OK now :)
– Reinderien
yesterday
There's no point to passing the
count
and flags
kwargs to re.sub
in this case.– Reinderien
yesterday
There's no point to passing the
count
and flags
kwargs to re.sub
in this case.– Reinderien
yesterday
Also, don't use the
re.sub
form at all. Use re.compile
and call sub
on the compiled regex object.– Reinderien
yesterday
Also, don't use the
re.sub
form at all. Use re.compile
and call sub
on the compiled regex object.– Reinderien
yesterday
Finally: you're applying
rename
and sub
on the same filename, which is incorrect. sub
must only be applied on the filename without path, and rename
must have the path.– Reinderien
yesterday
Finally: you're applying
rename
and sub
on the same filename, which is incorrect. sub
must only be applied on the filename without path, and rename
must have the path.– Reinderien
yesterday
you are correct for "sub must only be applied on the filename without path", I took a mistake on it, and "There's no point to passing the count and flags kwargs to re.sub in this case. " I just showing the function, and thanks for " Use re.compile and call sub on the compiled regex object.", updating my comment
– Aries_is_there
yesterday
you are correct for "sub must only be applied on the filename without path", I took a mistake on it, and "There's no point to passing the count and flags kwargs to re.sub in this case. " I just showing the function, and thanks for " Use re.compile and call sub on the compiled regex object.", updating my comment
– Aries_is_there
yesterday
Looks OK now :)
– Reinderien
yesterday
Looks OK now :)
– Reinderien
yesterday
add a comment |
You should use a recursive function like this:
import os
def rename_files(basedir):
for f in os.listdir(basedir):
if os.path.isdir(f):
rename_files(os.path.join(basedir, f))
else:
if "IMG_" in f:
os.rename(f, f.replace('IMG_', ''))
else:
pass
rename_files('C:/Users/user/FolderParent')
else; pass
has no effect; you can delete it and merge yourelse if
into anelif
.
– Reinderien
yesterday
Also, your path is wrong, because you have backslashes that will be interpreted as escapes. Use a raw string or use forward slashes.
– Reinderien
yesterday
Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance thanlistdir
.
– Reinderien
yesterday
1
Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
– Reinderien
yesterday
add a comment |
You should use a recursive function like this:
import os
def rename_files(basedir):
for f in os.listdir(basedir):
if os.path.isdir(f):
rename_files(os.path.join(basedir, f))
else:
if "IMG_" in f:
os.rename(f, f.replace('IMG_', ''))
else:
pass
rename_files('C:/Users/user/FolderParent')
else; pass
has no effect; you can delete it and merge yourelse if
into anelif
.
– Reinderien
yesterday
Also, your path is wrong, because you have backslashes that will be interpreted as escapes. Use a raw string or use forward slashes.
– Reinderien
yesterday
Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance thanlistdir
.
– Reinderien
yesterday
1
Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
– Reinderien
yesterday
add a comment |
You should use a recursive function like this:
import os
def rename_files(basedir):
for f in os.listdir(basedir):
if os.path.isdir(f):
rename_files(os.path.join(basedir, f))
else:
if "IMG_" in f:
os.rename(f, f.replace('IMG_', ''))
else:
pass
rename_files('C:/Users/user/FolderParent')
You should use a recursive function like this:
import os
def rename_files(basedir):
for f in os.listdir(basedir):
if os.path.isdir(f):
rename_files(os.path.join(basedir, f))
else:
if "IMG_" in f:
os.rename(f, f.replace('IMG_', ''))
else:
pass
rename_files('C:/Users/user/FolderParent')
edited 11 hours ago
answered yesterday
Piyush Singh
277
277
else; pass
has no effect; you can delete it and merge yourelse if
into anelif
.
– Reinderien
yesterday
Also, your path is wrong, because you have backslashes that will be interpreted as escapes. Use a raw string or use forward slashes.
– Reinderien
yesterday
Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance thanlistdir
.
– Reinderien
yesterday
1
Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
– Reinderien
yesterday
add a comment |
else; pass
has no effect; you can delete it and merge yourelse if
into anelif
.
– Reinderien
yesterday
Also, your path is wrong, because you have backslashes that will be interpreted as escapes. Use a raw string or use forward slashes.
– Reinderien
yesterday
Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance thanlistdir
.
– Reinderien
yesterday
1
Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
– Reinderien
yesterday
else; pass
has no effect; you can delete it and merge your else if
into an elif
.– Reinderien
yesterday
else; pass
has no effect; you can delete it and merge your else if
into an elif
.– Reinderien
yesterday
Also, your path is wrong, because you have backslashes that will be interpreted as escapes. Use a raw string or use forward slashes.
– Reinderien
yesterday
Also, your path is wrong, because you have backslashes that will be interpreted as escapes. Use a raw string or use forward slashes.
– Reinderien
yesterday
Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance than
listdir
.– Reinderien
yesterday
Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance than
listdir
.– Reinderien
yesterday
1
1
Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
– Reinderien
yesterday
Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
– Reinderien
yesterday
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210481%2frenaming-all-files-folders-in-first-children-folders-but-not-sub-children%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown