Recursively create hardlinks for a folder with part of the path changed

I have a src folder at: H:\data\ビッグバック・バニー. This folder has several subfolders which may or may not have ビッグバック・バニー in them too.

I want to recursively hardlink these while replacing the non-english characters with English to H:\data\Big Buck Bunny

here’s my script:

from pathlib import Path

src = Path(r"H:\data\ ビッグバック・バニー").resolve().rglob("*")

for file in src:
    parent = Path(str(file.parent).replace("ビッグバック・バニー", "Big Buck Bunny"))
    dst = parent / file.name

    print(f"Linking {file} -> {dst}")
    file.hardlink_to(dst)

I got this error:

Linking H:\data\ ビッグバック・バニー\[892478][AXYZ-2924][ビッグバック・バニー][Vol.1] -> H:\data\ Big Buck Bunny\[892478][AXYZ-2924][ビッグバック・バニー][Vol.1]
Traceback (most recent call last):
  File "H:\data\link.py", line 10, in <module>
    file.hardlink_to(dst)
  File "~\python312\current\Lib\pathlib.py", line 1396, in hardlink_to
    os.link(target, self)
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'H:\\data\\ Big Buck Bunny\\[892478][AXYZ-2924][ビッグバック・バニー][Vol.1]' -> 'H:\\data\\ ビッグバック・バニー\\[892478][AXYZ-2924][ビッグバック・バニー][Vol.1]'

I thought maybe folders aren’t supported? So added an is_file() check but same issue.

The src directory does exist:

Python 3.12.3 (tags/v3.12.3:f6650f9, Apr  9 2024, 14:05:25) [MSC v.1938 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pathlib import Path
>>> src = Path(r"H:\data\ ビッグバック・バニー")
>>> src.is_dir()
True
>>> len(tuple(src.rglob("*")))
425

Make sure the destination directories exist, and note the space at the start of the sub dir name in r"E:\data\ ビッグバック・バニー"

1 Like

I made some changes:

from pathlib import Path

src = Path(r"H:\data\ビッグバック・バニー").rglob("*")

for file in src:
    if file.is_file():

        parent = Path(str(file.parent).replace("ビッグバック・バニー", "Big Buck Bunny"))
        parent.mkdir(parents=True, exist_ok=True)
        
        dst = parent / file.name

        print(f"Linking {file} -> {dst}")
        file.hardlink_to(dst)

Still fails though:

Linking H:\data\ビッグバック・バニー\[892478][AXYZ-2924][ビッグバック・バニー][Vol.1]\SCANS\01.png -> H:\data\Big Buck Bunny\[892478][AXYZ-2924][Big Buck Bunny][Vol.1]\SCANS\01.png
Traceback (most recent call last):
  File "H:\data\link.py", line 14, in <module>
    file.hardlink_to(dst)
  File "~\python311\current\Lib\pathlib.py", line 1208, in hardlink_to
    os.link(target, self)
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'H:\\data\\Big Buck Bunny\\[892478][AXYZ-2924][Big Buck Bunny][Vol.1]\\SCANS\\01.png' -> 'H:\\data\\ビッグバック・バニー\\[892478][AXYZ-2924][ビッグバック・バニー][Vol.1]\\SCANS\\01.png'

a.hardlink_to(b) makes a a hardlink to b, i.e. b needs to exists beforehand. I think you have the order of arguments the wrong way around.

1 Like

yep, that worked. Thank you. I didn’t realize it’s different from rename and replace.