Структура каталогов инвертирования

Я совершил ужасную ошибку в очень продолжительном вычислении.

Одна часть вычисления хранит файлы результата в структуре каталогов как так:

path/to/first/[A,B,C,D]/[1,2,3,4,5]/outfiles

И другой делает это как это:

path/to/second/[1,2,3,4,5]/[A,B,C,D]/outfiles

Таким образом, когда часть 1 сценария хранит файлы, это создает каталог для, скажем, A, затем хранит повторения 1,2,3,4, и 5 как подкаталоги. Когда часть 2 делает свои вычисления, она создает каталог для повторения 1 и затем хранит первое повторение вычислений A, B, C, и D в подкаталогах.

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

Таким образом, path/to/second/1/A должен стать path/to/second/A/1, содержа файлы, которые были ранее 1/A. Существует ли простой способ достигнуть этого?

Более того с созданием временных каталогов, в то время как я использовал [A, B, C, D] и [1,2,3,4,5] в моем примере для ясности, каталоги для обеих иерархий являются просто числами и определенно имеют коллизии имени (то есть, вещи как 10/10 существуйте).

1
задан 19 May 2016 в 06:47

3 ответа

Вопрос состоит в том, чтобы на самом деле переименовать всех директоров, названных с целым числом капиталом с соответствующим индексом (+1) от алфавита, и наоборот:

1 -> A

в то время как, например.

C -> 3

Принятие Вас имеет не больше, чем 26 папок на уровне (количество букв в алфавите), вопрос не состоит в том, который усложнил, но мы должны принять во внимание несколько вещей:

  1. Мы должны переименовать каталоги от нижней части до вершины, так как движущиеся каталоги внутри между тем переименовали каталоги, перестанет работать.
  2. Так как Вы упоминаете возможные столкновения имени, мы должны сделать переименование в двух выполнениях:
    1. переименуйте директоров, добавив ерунду, уникальная строка для предотвращения столкновений имени
    2. удалите строку после того, как все переименование произошло

Это точно, что ниже делает сценарий:

Сценарий

#!/usr/bin/env python3
import string
import shutil
import os
import sys

reorg = sys.argv[1]

chars = list(string.ascii_uppercase)
nums = [str(i+1) for i, c in enumerate(chars)]

tempstring = "_temp1234"

# first step: rename from bottom to top
for root, dirs, files in os.walk(reorg, topdown = False):
    for dr in dirs:
        tempname = None
        if dr in chars:
            tempname = str(chars.index(dr)+1)+tempstring
        elif dr in nums:
            tempname = chars[nums.index(dr)]+tempstring
        if tempname:
             print(dr, tempname)
             shutil.move(root+"/"+dr, root+"/"+tempname)

# second step: remove the temporary string
for root, dirs, files in os.walk(reorg, topdown = False):
    for dr in dirs:
        if tempstring in dr:
            shutil.move(root+"/"+dr, root+"/"+dr.replace(tempstring, ""))

Использовать

  1. Скопируйте сценарий в пустой файл, сохраните его как reorg.py
  2. Выполните его с целенаправленным каталогом как аргумент:

    python3 /path/to/reorg.py /path/to/second
    

Как всегда, сначала примерьте образец.

2
ответ дан 19 May 2016 в 16:47
  • 1
    В моем случае нет никакого значка механизма, хотя Единица была установлена. Как продолжить двигаться? – Kristjan Adojaan 14 February 2018 в 09:02

Это должно сделать то, что Вы хотите в ударе:

#!/bin/bash
mkdir -p /path-to-second-new/{A,B,C,D}
for i in [1,2,3,4,5]
do 
    for j in [A,B,C,D]
    do
        cp -v /path-to-second/"$i"/"$j" /path-to-second-new/"$j"/"$i"
    done
done

Ваша нормальная структура должна затем быть в /path-to-second-new/ и Ваша начальная структура, нетронутая в /path-to-second/.

0
ответ дан 19 May 2016 в 16:47
  • 1
    @KristjanAdojaan Там являются несколькими возможностями в действии здесь - Ваша система обычно регистрирует Вас в без пароля? Я не вижу значок, пока я также не вижу подсказку ввода пароля. – Charles Green 14 February 2018 в 09:05

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

for a in */; do
    for b in $a/*/; do
        dir=${b##*//}
        mkdir -p $dir$a
        mv $a$dir* $dir$a
    done
    rm -rf $a
done

Это динамично захватывает имена папок, создает новую иерархию, перемещает все файлы и удаляет старые папки.

Извлечение папки второго уровня использует определенный взлом. Все имена каталогов $a закончатся в / (например, folder1/). Во втором для цикла я добавляю другую наклонную черту после $a (первое / в $a/*/), таким образом, каждая запись $b будет похожа folder1//folder2/. Эта двойная наклонная черта проигнорирована Unix, таким образом, я могу отфильтровать имя каталога путем срезания всего до и включая эту двойную наклонную черту с dir=${b##*//}.

0
ответ дан 19 May 2016 в 16:47

Другие вопросы по тегам:

Похожие вопросы: