Изменение нескольких файлов во время переноса из одной папки в другую Python - PullRequest
0 голосов
/ 25 мая 2020

Прямо сейчас у меня есть программа, которая перемещает файлы из подкаталогов в папке SOURCE в подкаталоги в папке DESTINATION. Файлы содержат такую ​​информацию: содержимое файла перед перемещением.

Теперь при переходе от ИСТОЧНИКА к НАЗНАЧЕНИЮ я хочу изменить перемещаемые файлы в двух местах.

  • Я хочу скопировать время и вставить его как TimeDif в поле Time. Тип остается Y, а значение должно быть текущим временем - значением Time.
  • Я хочу изменить значение Power * 10. Если значение Power = <1000, тогда тип остается N, в противном случае тип Power = Y </li>

Итак, после файла был перемещен из SOURCE в DESTINATION, он должен выглядеть так:

содержимое файла после перемещения.

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

import os, os.path
import time

#Make source, destination and archive paths.
source = r'c:\data\AS\Desktop\Source'
destination = r'c:\data\AS\Desktop\Destination'
archive = r'c:\data\AS\Desktop\Archive'

#Make directory paths and make sure to consider only directories under source.
for subdir in os.listdir(source):
    subdir_path = os.path.join(source, subdir)
    if not os.path.isdir(subdir_path):
        continue

#Now we want to get the absolute paths of the files inside those directories 
#and store them in a list.
    all_file_paths = [os.path.join(subdir_path, file) for file in os.listdir(subdir_path)]
    all_file_paths = [p for p in all_file_paths if os.path.isfile(p)]

#Exclude empty sub-directories
    if len(all_file_paths) == 0:
        continue

#Get only the newest files of those directories.
    newest_file_paths = max(all_file_paths, key=os.path.getctime)


#Now we are selecting the files which will be moved
#and make a destination path for them.
    for file_path in all_file_paths:
        if file_path == newest_file_paths and os.path.getctime(newest_file_paths) < time.time() - 120:
            dst_root = destination
        else:
            dst_root = archive

#Now its time to make the move.
        dst_path = os.path.join(dst_root, subdir, os.path.basename(file_path))
        os.rename(file_path, dst_path)

Ответы [ 3 ]

0 голосов
/ 25 мая 2020

Если файлы маленькие, вместо перемещения файлов вы можете просто:

  1. прочитать информацию из всех файлов
  2. найти данные, которые вы хотите заменить
  3. записать файлы с новыми данными в исходный каталог
  4. удалить старые файлы

Что-то вроде

def move_file(file_path, dst_path):
  with open(file_path, "r") as input_file, open(dst_path, "w") as output_file:
      for line in input_file:
         if <line meets criteria to modify>:
             <modify_line>
         print(line, file=output_file)
      for <data> in <additional_data>:
         print(<data>, file=output_file)

  # remove the old file
  os.remove(file_path)

Тогда вместо os. переименуйте в исходном коде вызовите функцию move_file

#Now we are selecting the files which will be moved
#and make a destination path for them.
    for file_path in all_file_paths:
        if file_path == newest_file_paths and os.path.getctime(newest_file_paths) < time.time() - 120:
            dst_root = destination
        else:
            dst_root = archive
#Now its time to make the move.
        dst_path = os.path.join(dst_root, subdir, os.path.basename(file_path))
        move_file(file_path, dst_path)

Вы можете реализовать это как

import os
import time
from datetime import datetime

SOURCE = r'c:\data\AS\Desktop\Source'
DESTINATION = r'c:\data\AS\Desktop\Destination'
ARCHIVE = r'c:\data\AS\Desktop\Archive'

def get_time_difference(date, time_string):
    """
    You may want to modify this logic to change the way the time difference is calculated.
    """
    time_difference = datetime.now() - datetime.strptime(f"{date} {time_string}", "%d-%m-%Y %H:%M")
    hours = time_difference.total_seconds() // 3600
    minutes = (time_difference.total_seconds() % 3600) // 60
    return f"{int(hours)}:{int(minutes)}"

def move_and_transform_file(file_path, dst_path, delimiter="\t"):
    """
    Reads the data from the old file, writes it into the new file and then 
    deletes the old file.
    """
    with open(file_path, "r") as input_file, open(dst_path, "w") as output_file:
        data = {
            "Date": None,
            "Time": None,
            "Power": None,
        }
        time_difference_seen = False
        for line in input_file:
            (line_id, item, line_type, value) = line.strip().split()
            if item in data:
                data[item] = value
                if not time_difference_seen and data["Date"] is not None and data["Time"] is not None:
                    time_difference = get_time_difference(data["Date"], data["Time"])
                    time_difference_seen = True
                    print(delimiter.join([line_id, "TimeDif", line_type, time_difference]), file=output_file)
                if item == "Power":
                    value = str(int(value) * 10)
            print(delimiter.join((line_id, item, line_type, value)), file=output_file)

    os.remove(file_path)

def process_files(all_file_paths, newest_file_path, subdir):
    """
    For each file, decide where to send it, then perform the transformation.
    """
    for file_path in all_file_paths:
        if file_path == newest_file_path and os.path.getctime(newest_file_path) < time.time() - 120:
            dst_root = DESTINATION
        else:
            dst_root = ARCHIVE

        dst_path = os.path.join(dst_root, subdir, os.path.basename(file_path))
        move_and_transform_file(file_path, dst_path)

def main():
    """
    Gather the files from the directories and then process them.
    """
    for subdir in os.listdir(SOURCE):
        subdir_path = os.path.join(SOURCE, subdir)
        if not os.path.isdir(subdir_path):
            continue

        all_file_paths = [
            os.path.join(subdir_path, p) 
            for p in os.listdir(subdir_path) 
            if os.path.isfile(os.path.join(subdir_path, p))
        ]

        if all_file_paths:
            newest_path = max(all_file_paths, key=os.path.getctime)
            process_files(all_file_paths, newest_path, subdir)

if __name__ == "__main__":
    main()
0 голосов
/ 25 мая 2020

@ MindOfMetalAndWheels Ваш код, конечно, просто изменяет файлы, а не перемещает их? Я хочу переместить и изменить их. Кстати, если я попытаюсь вставить ваш фрагмент кода в свой, я получу неверный синтаксис.

import os
import time
from datetime import datetime

SOURCE = r'c:\data\AS\Desktop\Source'
DESTINATION = r'c:\data\AS\Desktop\Destination'
ARCHIVE = r'c:\data\AS\Desktop\Archive'

def get_time_difference(date, time_string):
    """
    You may want to modify this logic to change the way the time difference is calculated.
    """
    time_difference = datetime.now() - datetime.strptime(f"{date} {time_string}", "%d-%m-%Y %H:%M")
    hours = time_difference.total_seconds() // 3600
    minutes = (time_difference.total_seconds() % 3600) // 60
    return f"{int(hours)}:{int(minutes)}"

def move_and_transform_file(file_path, dst_path, delimiter="\t"):
    """
    Reads the data from the old file, writes it into the new file and then 
    deletes the old file.
    """
    with open(file_path, "r") as input_file, open(dst_path, "w") as output_file:
        data = {
            "Date": None,
            "Time": None,
            "Power": None,
        }
        time_difference_seen = False
        for line in input_file:
            (line_id, item, line_type, value) = line.strip().split()
            if item in data:
                data[item] = value
                if not time_difference_seen and data["Date"] is not None and data["Time"] is not None:
                    time_difference = get_time_difference(data["Date"], data["Time"])
                    time_difference_seen = True
                    print(delimiter.join([line_id, "TimeDif", line_type, time_difference]), file=output_file)
                if item == "Power":
                    value = str(int(value) * 10)
            print(delimiter.join((line_id, item, line_type, value)), file=output_file)

    os.remove(file_path)

def process_files(all_file_paths, newest_file_path, subdir):
    """
    For each file, decide where to send it, then perform the transformation.
    """
    for file_path in all_file_paths:
        if file_path == newest_file_path and os.path.getctime(newest_file_path) < time.time() - 120:
            dst_root = DESTINATION
        else:
            dst_root = ARCHIVE

        dst_path = os.path.join(dst_root, subdir, os.path.basename(file_path))
        move_and_transform_file(file_path, dst_path)

def main():
    """
    Gather the files from the directories and then process them.
    """
    for subdir in os.listdir(SOURCE):
        subdir_path = os.path.join(SOURCE, subdir)
        if not os.path.isdir(subdir_path):
            continue

        all_file_paths = [
            os.path.join(subdir_path, p) 
            for p in os.listdir(subdir_path) 
            if os.path.isfile(os.path.join(subdir_path, p))
        ]

        if all_file_paths:
            newest_path = max(all_file_paths, key=os.path.getctime)
            process_files(all_file_paths, newest_path, subdir)

if __name__ == "__main__":
    main()
0 голосов
/ 25 мая 2020

Вы не можете изменить способ его перемещения. Сначала вам нужно переместить его, а затем вы сможете выполнять свою работу. Для этого вы можете сохранить конечные места назначения ваших файлов (включая подкаталоги в имени) в массиве и повторить его позже, чтобы открывать файлы и выполнять свою работу.

Вот минимальный пример

def changeFile(fileName):
    # do your desired work here
    pass

files = ["dir/subdir1/file1", "dir/file"]

for file in files:
    os.rename(file, newPath)
    changeFile(newPath)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...