Я совершил ужасную ошибку в очень продолжительном вычислении.
Одна часть вычисления хранит файлы результата в структуре каталогов как так:
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) от алфавита, и наоборот:
1 -> A
в то время как, например.
C -> 3
Принятие Вас имеет не больше, чем 26 папок на уровне (количество букв в алфавите), вопрос не состоит в том, который усложнил, но мы должны принять во внимание несколько вещей:
Это точно, что ниже делает сценарий:
#!/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, ""))
reorg.py
Выполните его с целенаправленным каталогом как аргумент:
python3 /path/to/reorg.py /path/to/second
Как всегда, сначала примерьте образец.
Это должно сделать то, что Вы хотите в ударе:
#!/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/
.
Я сталкивался с той же проблемой недавно в ситуации, где это не было практично для списка всех папок вручную. Желая использовать сценарий удара, я придумал следующее:
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##*//}
.