Renaming all files/folders in first children folders but not sub-children












2














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")









share|improve this question





























    2














    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")









    share|improve this question



























      2












      2








      2







      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")









      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 3 hours ago









      Jamal

      30.3k11116226




      30.3k11116226










      asked yesterday









      MagTun

      1354




      1354






















          3 Answers
          3






          active

          oldest

          votes


















          3














          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 of listdir

          • Do not call chdir; there's no point

          • Don't call replace; the pattern check and the replacement operation can be combined by using sub

          • Don't store a list of all_subfolders; simply iterate over the results






          share|improve this answer





























            2














            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.






            share|improve this answer























            • 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










            • 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










            • Looks OK now :)
              – Reinderien
              yesterday



















            -2














            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')





            share|improve this answer























            • 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










            • Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance than listdir.
              – Reinderien
              yesterday






            • 1




              Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
              – Reinderien
              yesterday











            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
            });


            }
            });














            draft saved

            draft discarded


















            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









            3














            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 of listdir

            • Do not call chdir; there's no point

            • Don't call replace; the pattern check and the replacement operation can be combined by using sub

            • Don't store a list of all_subfolders; simply iterate over the results






            share|improve this answer


























              3














              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 of listdir

              • Do not call chdir; there's no point

              • Don't call replace; the pattern check and the replacement operation can be combined by using sub

              • Don't store a list of all_subfolders; simply iterate over the results






              share|improve this answer
























                3












                3








                3






                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 of listdir

                • Do not call chdir; there's no point

                • Don't call replace; the pattern check and the replacement operation can be combined by using sub

                • Don't store a list of all_subfolders; simply iterate over the results






                share|improve this answer












                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 of listdir

                • Do not call chdir; there's no point

                • Don't call replace; the pattern check and the replacement operation can be combined by using sub

                • Don't store a list of all_subfolders; simply iterate over the results







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered yesterday









                Reinderien

                3,160720




                3,160720

























                    2














                    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.






                    share|improve this answer























                    • 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










                    • 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










                    • Looks OK now :)
                      – Reinderien
                      yesterday
















                    2














                    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.






                    share|improve this answer























                    • 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










                    • 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










                    • Looks OK now :)
                      – Reinderien
                      yesterday














                    2












                    2








                    2






                    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.






                    share|improve this answer














                    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.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited yesterday

























                    answered yesterday









                    Aries_is_there

                    687211




                    687211












                    • 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










                    • 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










                    • Looks OK now :)
                      – 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










                    • 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










                    • 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











                    -2














                    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')





                    share|improve this answer























                    • 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










                    • Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance than listdir.
                      – Reinderien
                      yesterday






                    • 1




                      Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
                      – Reinderien
                      yesterday
















                    -2














                    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')





                    share|improve this answer























                    • 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










                    • Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance than listdir.
                      – Reinderien
                      yesterday






                    • 1




                      Finally: this solution is wholly incorrect. It doesn't have the depth check that the OP requires.
                      – Reinderien
                      yesterday














                    -2












                    -2








                    -2






                    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')





                    share|improve this answer














                    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')






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 11 hours ago

























                    answered yesterday









                    Piyush Singh

                    277




                    277












                    • 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










                    • Read about docs.python.org/3/library/os.html#os.scandir - it claims higher performance than listdir.
                      – 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










                    • 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






                    • 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


















                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    Morgemoulin

                    Scott Moir

                    Souastre