1
\$\begingroup\$

The filenames.txt contains all the names of the files that you want to change in a given directory. It is generated by:

import os

walk = os.walk("./app/")

for dirpath, dirs, files in walk:
    for filename in files:
        fpath = os.path.join(dirpath, filename)
        with open("filenames.txt", "a") as f:
            f.write(filename + "\n")

The Test directory is the directory whose files you are targeting.

"""Rename files.
Rename file references containing `-` with `_`
"""
import os

# Directory to traverse
walk = os.walk('./Test/')

# A file containing filenames that you want to change.
# Already generated
with open("filenames.txt") as filenames_to_change:
    names = filenames_to_change.read().splitlines()

for dirpath, dirs, files in walk:
    for filename in files:
        fpath = os.path.join(dirpath, filename)

        for name in names:
            old_name = name
            new_name = name.replace('-', '_')
            print("{} >>> {}".format(old_name, new_name))

            with open(fpath) as f:
                s = f.read()
            s = s.replace(old_name, new_name)
            with open(fpath, "w") as f:
                f.write(s)
\$\endgroup\$
3
  • 2
    \$\begingroup\$ This doesn't seem to rename files - rather, it copies them with a different name and leaves the original. Was that your intent? \$\endgroup\$
    – Pimgd
    Jul 3, 2016 at 12:55
  • \$\begingroup\$ If you just wanted to rename files, os.rename does it in a simple function call. \$\endgroup\$ Jul 4, 2016 at 13:51
  • \$\begingroup\$ @Pimgd it renames the file references inside them \$\endgroup\$ Jul 4, 2016 at 15:01

1 Answer 1

2
\$\begingroup\$

For each filename you want to replace in the content, you open each file, mutate the content and write it back. Meaning that if you want to modify 10 filenames, you open each file 10 times and write it back 10 times.

This is clearly inefficient, you should open each file once, perform the 10 modifications you need and then write it back.

You also recompute new_name for each file which is not necessary as you could store this information somehow.

Last but not least, you could define some function to organize the code and give meaning to your actions:

"""
Rename references to filenames inside content of files in a directory.

Rename file references containing `-` with `_`
"""

import os


def update_references(conversion_table, directory):
    for root, dirs, files in os.walk(directory):
        for filename in files:
            path = os.path.join(root, filename)

            # Read initial content from file
            with open(path) as f:
                content = f.read()

            # Update content with new references
            for old_name, new_name in conversion_table.items():
                content = content.replace(old_name, new_name)

            # Update file with new content
            with open(path, "w") as f:
                f.write(content)


if __name__ == '__main__':
    # A file containing filenames that you want to change.
    # Already generated
    with open("filenames.txt") as filenames_to_change:
        names = filenames_to_change.read().splitlines()

    renamed = {name: name.replace('-', '_') for name in names}
    update_references(renamed, './Test/')
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.