Как изменить строку в определенном теге в нижний регистр в нескольких файлах - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть следующее требование, которое я пытаюсь выполнить в Windows 10 с помощью сценария Python:

  1. Рекурсивно меняйте все имена файлов на строчные в нескольких папках. Для этого я использовал следующий код:

    import os path = "C://Users//shilpa//Desktop//content"
    for dir,subdir,listfilename in os.walk(path):
        for filename in listfilename:  
            new_filename = filename.lower()
            src = os.path.join(dir, filename) 
            dst = os.path.join(dir, new_filename) 
            os.rename(src,dst)
    
  2. Обновите ссылки на эти файлы, встроенные в определенный тег. Тег здесь <img href=(filename.png)>. Здесь <img href=> является константой, а имена файлов filename.png отличаются.

Итак, вот пример:

Существующие имена файлов:

  • ABC.dita
  • XYZ.dita
  • IMG.PNG

Они указаны в разных файлах, например, IMG.PNG указан в XYZ.dita.

После шага 1 они изменяются следующим образом:

  • abc.dita
  • xyz.dita
  • img.png

Это нарушит все ссылки, включенные в разные файлы.

Я хочу обновить все ссылки на измененные имена файлов, чтобы ссылки оставались нетронутыми.

У меня нет никаких опыт работы с Python и только для начинающих. Чтобы выполнить шаг 2, я должен быть в состоянии использовать регулярные выражения и найти шаблон, скажем,

<img href="(this will be a link to the IMG.PNG>". Это будет частью файла .dita.

После шага 1 ссылка в файле будет разорвана.

Как я могу внести изменения в имя файла, а также сохранить их ссылки? Задача здесь - найти и заменить старые имена новыми именами во всех файлах.

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 29 апреля 2020

Я предполагаю, что у вас есть папка, содержащая все соответствующие файлы. Таким образом, проблема разделена на две части:

  1. Запуск в al oop над файлами
  2. Для каждого файла опустите ссылки

Loopin Over Файлы

Это можно сделать с помощью glob или os.walk.

import os

upper_directory = "[insert your directory]"
for dirpath, directories, files in os.walk(upper_directory):
    for fname in files:
        path = os.path.join(dirpath, fname)
        lower_file_references(path)

Строчные ссылки. Ссылки

Если у вас есть путь к файлу, вам нужно прочитать данные из него:

with open(path) as f:
    s = f.read()

Когда у вас есть данные файлов ссылок, вы можете использовать этот код для понижения строки ссылки:

head = "<img href="
tail = ">"
img_start = s.find(head, start)
while img_start != -1:
    img_end = s.find(">", img_start)
    s = s[:img_start] +s[img_start:img_end].lower() + s[img_end:]
    img_start = img_end

По-другому вы можно использовать какой-то XML модуль синтаксического анализа. Например, BeautifulSoup, это поможет избежать таких проблем, как href= против href =

from bs4 import BeautifulSoup as bs

s = bs(s)
imgs = s.find_all("img")
for i in imgs:
    if "href" in i.attrs:
        i.attrs["href"] = i.attrs["href"].lower()
s = str(s)

В обоих случаях вы можете переписать файлы. Вы можете сделать это следующим образом:

with open(path, "w") as f:
    f.write(s)

Соберите все вместе

import os
from bs4 import BeautifulSoup as bs

def lower_file_references(file_path):
    with open(path) as f:
        s = f.read()
    s = bs(s)
    imgs = s.find_all("img")
    for i in imgs:
        if "href" in i.attrs:
            i.attrs["href"] = i.attrs["href"].lower()
    s = str(s)
    with open(path, "w") as f:
        f.write(s)

upper_directory = "[insert your directory]"
for dirpath, directories, files in os.walk(upper_directory):
    for fname in files:
        path = os.path.join(dirpath, fname)
        lower_file_references(path)

Я должен сказать, что это простой метод, который будет отлично работать, если ваши файлы не большие , Если у вас есть большие файлы, которые невозможно прочитать в память одновременно, или много файлов, вы можете подумать о том, как избежать чтения данных всех файлов.

...