2

I'm relatively new to Python, so sorry if I butcher any terms or make dumb questions. My goal here is to rename any filename in a specific directory containing the string "&" to an "x". So far I've tried making python look for these files and print their filenames but get back an empty output, even though there's a test file that contains the string "&".

Here is my code:

import fnmatch
import os

for file in os.listdir('B:\\Music'):
    if fnmatch.fnmatch(, '*&'):
        print(file)
adamgy
  • 4,543
  • 3
  • 16
  • 31

2 Answers2

1

You need a * before and after the character you are trying to match:

import fnmatch
import os

for file in os.listdir('B:\\Music'):
    if fnmatch.fnmatch(file, '*&*'):
        print(file)

Explanation:

* matches everything, therefore:

*& matches every string ending with &

&* matches every string starting with &

*&* matches every string that contains &

adamgy
  • 4,543
  • 3
  • 16
  • 31
  • Oh, thanks! Thats solved. What can I replace the if statement with so it renames the "&" to an "x"? – Somebody Unknown Jul 07 '20 at 16:27
  • If my answer was helpful, consider marking it as accepted with the big check mark next to the post. To rename the file, you can do something like new_filename = file.replace('&', 'x'), then os.rename(file, new_filename) – adamgy Jul 07 '20 at 16:38
  • I get the following error: _"FileNotFoundError: [WinError 2] The system cannot find the file specified:"_ I think it might be searching for the file in the wrong place (?. I read something about using (os.path.join), or is that not related. – Somebody Unknown Jul 07 '20 at 16:53
  • yes, since "file" only contains the filename, but if the file is not in the current directory, you need to add the directory as well so that the rename method can find the file. You can do that using os.path.join(), or even with simple string operations – adamgy Jul 07 '20 at 17:02
  • Could I get an example on how to define the path for the file? be it with os.path.join() or with simple strings as you mentioned [ because, as I said, I'm pretty new to python :,) ] – Somebody Unknown Jul 07 '20 at 17:07
  • You could probably use os.rename('B:\\Music\' + file, 'B:\\Music\' + new_filename) – adamgy Jul 07 '20 at 17:11
1
import os

directory = 'B:\\Music'
for basename in os.listdir(directory):
    if '&' in basename:
        os.rename(
            os.path.join(directory, basename), 
            os.path.join(directory, basename.replace('&', 'x'))
        )

As I said in the main post comment, you don't need fnmatch, because you only wanted to tell if the basename contains &. Using in should be enough.

PS: Getting back to your title, you may refer to @adamgy's answer to get the correct way to use fnmatch to match something in the future.

Panwen Wang
  • 3,573
  • 1
  • 18
  • 39