Правильно реализовать os.path.join() для рекурсивной замены строки в именах файлов и каталогов

#python #python-3.x #python-2.7

#python #python-3.x #python-2.7

Вопрос:

Основной вопрос о правильной реализации os.path.join() . Вероятно, я здесь упускаю что-то основное.

Здесь, в моей приведенной ниже функции Python, я пытаюсь рекурсивно заменить строку из имени файла или каталога на каждом уровне вложенности (глубины).

Таким образом, приведенная ниже функция работает корректно для замены всех вхождений строки «free» и замены ее пустой строкой «» из приведенной ниже файловой структуры на каждом вложенном уровне

введите описание изображения здесь

 for root, dirs, files in os.walk(sys.argv[1], topdown=False):
    for f in files:
        shutil.move(
            os.path.join(root, f), root "/" f.replace("free", "").strip()
        )
    for dr in dirs:
        shutil.move(
            os.path.join(root, dr), root "/" dr.replace("free", "").strip()
        )
  

И для выполнения вышеупомянутого мне нужно сохранить скрипт как some_name.py запустите его с каталогом в качестве аргумента:

 python3 /path/to/some_name.py <directory>
  

Но в приведенном выше сценарии я хочу заменить часть root "/" f на os.path.join() , чтобы заставить код работать в разных операционных системах.

Но как только я проведу рефакторинг этой части, как показано ниже

 for root, dirs, files in os.walk(sys.argv[1], topdown=False):
    for f in files:
        shutil.move(
            os.path.join(root, f), os.path.join(root, f).replace("free", "").strip()
        )
    for dr in dirs:
        shutil.move(
            os.path.join(root, dr), root "/" dr.replace("free", "").strip()
        )
  

Я получаю сообщение об ошибке ниже FileNotFoundError: [Errno 2] No such file or directory: '/home/paul/Pictures/free-so/so/so/test.txt' -> '/home/paul/Pictures/-so/so/so/test.txt'

Полная ошибка, как показано ниже.

 Traceback (most recent call last):
  File "/usr/lib/python3.8/shutil.py", line 788, in move
    os.rename(src, real_dst)
FileNotFoundError: [Errno 2] No such file or directory: '/home/paul/Pictures/free-so/so/so/test.txt' -> '/home/paul/Pictures/-so/so/so/test.txt'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "replace-string-in-directory-name-and-filenames-recursively.py", line 91, in <module>
    shutil.move(
  File "/usr/lib/python3.8/shutil.py", line 802, in move
    copy_function(src, real_dst)
  File "/usr/lib/python3.8/shutil.py", line 432, in copy2
    copyfile(src, dst, follow_symlinks=follow_symlinks)
  File "/usr/lib/python3.8/shutil.py", line 261, in copyfile
    with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
FileNotFoundError: [Errno 2] No such file or directory: '/home/paul/Pictures/-so/so/so/test.txt'

  

Ответ №1:

Вы заменяете «свободно» везде, включая путь root , и он не может найти переименованный каталог, в который нужно поместить файл.

Попробуйте заменить

 shutil.move(
    os.path.join(root, f), os.path.join(root, f).replace("free", "").strip()
)
  

с помощью:

 shutil.move(
    os.path.join(root, f), os.path.join(root, f.replace("free", "").strip())
)
  

Вы хотите, чтобы замена выполнялась только для имени файла ( f ), а не для root части пути.

Вы также можете внести аналогичные изменения в dirs часть.

Ответ №2:

Вероятно, вам нужно shutil.move(os.path.join(root, f), os.path.join(root, f.replace("free", "").strip()))

Пример:

 for root, dirs, files in os.walk(sys.argv[1], topdown=False):
    for f in files:
        shutil.move(
            os.path.join(root, f), os.path.join(root, f.replace("free", "").strip())
        )   # ! Update
    for dr in dirs:
        shutil.move(
            os.path.join(root, dr), os.path.join(root, dr.replace("free", "").strip())
        )