5

I am trying to identify all files with certain names in a folder. I am using standard code to do that looking like this:

for paths, subdirs, files in os.walk(start_dir, topdown=True):
    for file in files:
        print(os.path.join(paths, file))

My problem is about the output of this code in windows machine, basically dynamic parts of the path have wrong slash sign:

D:/JAJA/Projects/DAF/AIM/WEBAPP/trunk/src/main/java/ie/gov/agriculture/aim\aes\AesSheetNumberEntity.java
D:/JAJA/Projects/DAF/AIM/WEBAPP/trunk/src/main/java/ie/gov/agriculture/aim\aes\DocumentReceivedDetailEntity.java
D:/JAJA/Projects/DAF/AIM/WEBAPP/trunk/src/main/java/ie/gov/agriculture/aim\aes\DocumentReceivedEntity.java
D:/JAJA/Projects/DAF/AIM/WEBAPP/trunk/src/main/java/ie/gov/agriculture/aim\aes\DocumentTypeEntity.java

start folder which was given is:

D:/JAJA/Projects/DAF/AIM/WEBAPP/trunk/src/main/java/ie/gov/agriculture/aim

and the folder separator is unix one: "/"

while all subsequent subfolders found by os.walk function have windows slash instead: "\"

So at the end I have invalid path which cannot be used straight away. Is this a bug in python os library or what actually?

Currently I can easily replace wrong separator with the right one but I am wondering if it is the only way?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
smoczyna
  • 489
  • 6
  • 18
  • I thought the Python standard was `os.sep.join(sequence_to_join)` ? I would guess that the use of `os.path` here may be what's causing your issue – Andrew Nov 26 '18 at 12:40
  • 1
    The paths are *not actually wrong*, they will work with the mix of slashes. Both are valid. Windows has **two** path separators and it doesn't matter if you mix them. – Martijn Pieters Nov 26 '18 at 12:41
  • If you want to normalise the paths to a single separator, do so explicitly, using `os.path.normpath()` – Martijn Pieters Nov 26 '18 at 12:42
  • Your example seems mixed up: path starts with `D:JAJA` (no slash), is that really what you get? – Joël Nov 26 '18 at 12:43
  • 1
    @Joël: lets assume that that's a simple 'anonymise the string for Stack Overflow posting' editing error. I added the slashes back in. – Martijn Pieters Nov 26 '18 at 12:47
  • It appears that none of your comments Lads actually works. Andrew, I think both way might be equivalent and there is no difference in output. Martijn, perhaps both separators work in Widows but not when you try to create a new file with such path, it will fail. Joel this is pointless and unimportant remark which has nothing common with the problem. – smoczyna Nov 26 '18 at 14:28
  • @smoczyna That's a question when I tried to understand what gets wrong; writing that something is "pointless and unimportant" quite pedantic until the final answer it found... which it appears is not was you expected, as it's often the case, for I and others. Therefore, please stay polite. – Joël Nov 26 '18 at 22:28

2 Answers2

5

There is no actual problem here. Windows supports two path separators; the forward and backward slashes are both valid and supported, even when mixed. One is the os.sep (\), and the other the os.altsep character (/).

os.path.join() user os.sep to join paths, but won't replace os.altsep in the input paths. os.walk() just uses os.path.join() to build the first element of each (path, files, directories) tuple it generates

If this bothers you, normalise your paths, using the os.path.normpath() function:

On Windows, it converts forward slashes to backward slashes.

So normalise the path passed to os.walk():

for paths, subdirs, files in os.walk(os.path.normpath(start_dir), topdown=True):
    for file in files:
        full_path = os.path.join(paths, file)
        print(full_path)

or normalise the paths generated in the loop:

for paths, subdirs, files in os.walk(start_dir, topdown=True):
    for file in files:
        full_path = os.path.join(paths, file)
        normalised = os.path.normpath(full_path)
        print(normalised)

or normalise the input string:

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • it did bother me that the path is mixed because when you try to create a new file with such path it will fail, however you answer fills the bill – smoczyna Nov 26 '18 at 14:40
  • @smoczyna: no, creating a new file with a path that mixes forward and backward slashes will not fail, everything else being equal (i.e. if that path with only forward or only backward slashes can be created, then it can be created with mixed slashes too0. – Martijn Pieters Nov 26 '18 at 14:50
  • Well I have permission denied error when I try. It is obviously not true as I am operating within my home folder only. – smoczyna Nov 26 '18 at 15:18
  • @smoczyna: Now try again with `os.path.normpath()`. **You'll get the same exception**. – Martijn Pieters Nov 26 '18 at 15:23
  • You actually right, that was my fault, not the path, thanks – smoczyna Nov 26 '18 at 15:58
2

Use os.path.join(path).replace("\\","/") or os.path.normpath().replace("\\","/") will convert path to all forward slash '/'

imanzabet
  • 2,752
  • 2
  • 26
  • 19