Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Синхронизация имен папок в разных директориях при помощи батника. (http://forum.oszone.net/showthread.php?t=346021)

NuclearBox 02-08-2020 09:59 2929923

Синхронизация имен папок в разных директориях при помощи батника.
 
Здравствуйте.
В нескольких директориях расположены одинаковые папки с файлами. Неодинаковых нет, но еще могут быть разные файлы в корне.

Начало

DIR1
  • F1
  • F2
  • F3
  • x.txt

DIR2
  • F1
  • F2
  • F3
  • y.txt

DIR3
  • F1
  • F2
  • F3
  • z.txt


Как, вручную добавив в одной из директорий к названиям нескольких папок определенный префикс (в примере это "0-"),..

Изменение вручную

DIR1
  • 0-F1
  • F2
  • 0-F3
  • x.txt


...потом при помощи батника сделать те же изменения в именах папок в остальных директориях?

После батника

DIR2
  • 0-F1
  • F2
  • 0-F3
  • y.txt

DIR3
  • 0-F1
  • F2
  • 0-F3
  • z.txt


Директории в разных местах и на разную глубину, но одни и те же - их можно прописать через set=.

Префикс тоже можно прописать в переменную, по нему определить вероятное изменение, разложить названия папок на префикс и имя, и использовать их для переименования папок в других директориях.

Сложности:
- реализация возможна только стандартным батником.
- префикс может присваиваться не в одной директории, как в примере в DIR1, а в разных директориях.
- в идеале, нужна такая же обратная функция - синхронизация имен папок после удаления префикса.

Iska 02-08-2020 13:15 2929943

NuclearBox, быть может, Вы расскажете — зачем всё это нужно? Для решения какой задачи Вы выбрали такой способ решения?

NuclearBox 02-08-2020 14:37 2929956

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

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

Задача является развитием вот этой темы http://forum.oszone.net/post-2872146.html
Но только теперь нельзя трогать реестр (reg) для организации контекстного меню, и задач стало больше - не только удаление похожих папок.
Оптимальное решение вижу через префиксы-метки.

Iska 03-08-2020 06:40 2930020

NuclearBox, тогда уж лучше расширения менять для каталогов, и не трогать имена: пакетные файлы не лучший выбор для работы со строками.

megaloman 03-08-2020 08:50 2930032

NuclearBox, подробнее об именах F1, F2, F3... Что в них, какие символы, есть ли там пробелы?
Возможно ли, например 0-0-F1, или префикс может быть присвоен только один раз
Идея Iska, кстати, мне тоже нравится больше, чем префиксы, например, F1.OLD, но это не сильно принципиально.
Цитата:

В нескольких директориях расположены одинаковые папки с файлами.
Эти директории расположены в какой-то общей папке и там необходимо просмотреть все директории, или их имена надо как-то перечислить?

NuclearBox 03-08-2020 13:33 2930044

Iska, так и задумано - префиксы будут применяться только к папкам (в примере F1, F2, F3), не к файлам. Если речь идет о варианте типа F1.OLD - он в принципе приемлем. Может быть "постфикс" вместо префикса. Но имена папок могут содержать свои точки в имени, и сортировка папок по началу имени удобнее, чем по окончанию имени.

megaloman, имена папок ограничены только общими правилами имен - нет кавычек, слэшей и прочего, что нельзя использовать в имени папки вручную. Могут быть пробелы, тильды, точки, кириллица, латиница, цифры... Префикс можно присваивать много раз. Главное, чтобы папки в разных директориях (в примере DIR1, DIR2, DIR3) имели одинаковые имена в каждой из них.
По поводу варианта F1.OLD - префикс выполняет роль некой метки. Метка позволит определить оригинальные имена тех папок, с которыми во всех директориях DIR (а их больше трех) необходимо выполнить какие-либо действия. Фактически, метка работает как маска для дальнейшей обработки. Например, удаления по маске, изменения по маске, включения в обработку по маске.
Цитата:

Цитата megaloman
Эти директории расположены в какой-то общей папке и там необходимо просмотреть все директории, или их имена надо как-то перечислить? »

Директории не имеют общего пути, их надо перечислить через set=
Одна может находиться на C:\DIR1 , другая на C:\AAA\DIR2 , третья на C:\BBB\DIR3

NuclearBox 18-08-2020 02:20 2931508

"...Напрасно ждал Наполеон..."

NuclearBox 26-08-2020 22:40 2932177

Думал, задача будет не такой сложной.
Переименовав одни папки, с помощью батника переименовать одноименные им папки в заранее известных директориях, в пределах файловой системы одного компьютера.
Iska, megaloman, пожалуйста, напишите, что решения нет, если его нет. А то я подзастрял в "режиме ожидания".
В любом случае, ветеранам спасибо. Выручали не раз.

Iska 27-08-2020 13:26 2932213

NuclearBox, решение есть. Только выглядеть оно должно не так, как Вы описываете.

Я вижу это так:

1. Есть строка-префикс.
2. Есть путь к каталогу-источнику:
Цитата:

Цитата NuclearBox
что-то там\DIR1 »

3. Есть пути к каталогам-приёмникам:
Цитата:

Цитата NuclearBox
что-то там\DIR2
что-то там\DIR3
»

4. Есть имена подкаталогов, в которые нужно добавлять/удалять префикс:
Цитата:

Цитата NuclearBox
F1
F3 »

Туда:
Скрытый текст
Код:

Option Explicit

Dim strPrefix
Dim strSourceFolder
Dim arrDestFolders
Dim arrSubFolders

Dim objFSO

Dim strDestFolder
Dim strSubFolder


strPrefix      = "0-"

strSourceFolder = "C:\Мои проекты\0319\DIR1"
arrDestFolders  = Array( _
        "C:\Мои проекты\0319\DIR2", _
        "C:\Мои проекты\0319\DIR3" _
)
arrSubFolders  = Array( _
        "F1", _
        "F3" _
)


Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

If Not objFSO.FolderExists(strSourceFolder) Then
        WScript.Echo "Can't find source folder [" & strSourceFolder & "]."
        WScript.Quit 1
Else
        For Each strSubFolder In arrSubFolders
                If Not objFSO.FolderExists(objFSO.BuildPath(strSourceFolder, strSubFolder)) Then
                        WScript.Echo "Can't find subfolder [" & strSubFolder & "] in source folder [" & strSourceFolder & "]."
                        WScript.Quit 2
                End If
        Next
End If

For Each strDestFolder In arrDestFolders
        If Not objFSO.FolderExists(strDestFolder) Then
                WScript.Echo "Can't find destination folder [" & strDestFolder & "]."
                WScript.Quit 3
        Else
                For Each strSubFolder In arrSubFolders
                        If Not objFSO.FolderExists(objFSO.BuildPath(strDestFolder, strSubFolder)) Then
                                WScript.Echo "Can't find subfolder [" & strSubFolder & "] in destination folder [" & strDestFolder & "]."
                                WScript.Quit 4
                        End If
                Next
        End If
Next

For Each strSubFolder In arrSubFolders
        With objFSO.GetFolder(objFSO.BuildPath(strSourceFolder, strSubFolder))
                WScript.StdOut.Write .Path & " ---> "
                .Name = strPrefix & .Name
                WScript.StdOut.WriteLine .Path
        End With
       
        For Each strDestFolder In arrDestFolders
                With objFSO.GetFolder(objFSO.BuildPath(strDestFolder, strSubFolder))
                        WScript.StdOut.Write .Path & " ---> "
                        .Name = strPrefix & .Name
                        WScript.StdOut.WriteLine .Path
                End With
        Next
       
        WScript.StdOut.WriteLine
Next

Set objFSO = Nothing

WScript.Quit 0


и обратно:
Скрытый текст
Код:

Option Explicit

Dim strPrefix
Dim strSourceFolder
Dim arrDestFolders
Dim arrSubFolders

Dim objFSO

Dim strDestFolder
Dim strSubFolder


strPrefix      = "0-"

strSourceFolder = "C:\Мои проекты\0319\DIR1"
arrDestFolders  = Array( _
        "C:\Мои проекты\0319\DIR2", _
        "C:\Мои проекты\0319\DIR3" _
)
arrSubFolders  = Array( _
        "F1", _
        "F3" _
)


Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

If Not objFSO.FolderExists(strSourceFolder) Then
        WScript.Echo "Can't find source folder [" & strSourceFolder & "]."
        WScript.Quit 1
Else
        For Each strSubFolder In arrSubFolders
                If Not objFSO.FolderExists(objFSO.BuildPath(strSourceFolder, strPrefix & strSubFolder)) Then
                        WScript.Echo "Can't find subfolder [" & strPrefix & strSubFolder & "] in source folder [" & strSourceFolder & "]."
                        WScript.Quit 2
                End If
        Next
End If

For Each strDestFolder In arrDestFolders
        If Not objFSO.FolderExists(strDestFolder) Then
                WScript.Echo "Can't find destination folder [" & strDestFolder & "]."
                WScript.Quit 3
        Else
                For Each strSubFolder In arrSubFolders
                        If Not objFSO.FolderExists(objFSO.BuildPath(strDestFolder, strPrefix & strSubFolder)) Then
                                WScript.Echo "Can't find subfolder [" & strPrefix & strSubFolder & "] in destination folder [" & strDestFolder & "]."
                                WScript.Quit 4
                        End If
                Next
        End If
Next

For Each strSubFolder In arrSubFolders
        With objFSO.GetFolder(objFSO.BuildPath(strSourceFolder, strPrefix & strSubFolder))
                WScript.StdOut.Write .Path & " ---> "
                .Name = Mid(.Name, Len(strPrefix) + 1)
                WScript.StdOut.WriteLine .Path
        End With
       
        For Each strDestFolder In arrDestFolders
                With objFSO.GetFolder(objFSO.BuildPath(strDestFolder, strPrefix & strSubFolder))
                        WScript.StdOut.Write .Path & " ---> "
                        .Name = Mid(.Name, Len(strPrefix) + 1)
                        WScript.StdOut.WriteLine .Path
                End With
        Next
       
        WScript.StdOut.WriteLine
Next

Set objFSO = Nothing

WScript.Quit 0


На WSH. Если будете исполнять не под cscript.exe, а под умолчальным wscript.exe — закомментируйте WScript.StdOut.Write/WScript.StdOut.WriteLine'ы.

megaloman 28-08-2020 14:22 2932283

CMD - Добавление префикса
Код:

@Echo Off
cls
        Set DAll="Z:\Box_In\Dir1" "Z:\Box_In\Dir2" "Z:\Box_In\Dir3" "D:\Май гад!"
        Set "Pref=0-"

        2>nul Del "%Temp%\%~nx0.In"
        FOR /D %%d IN (%DAll%) DO FOR /F "usebackq delims=" %%i IN (`2^>nul Dir "%%~d" /B /A:D`) DO (
                Set "Name=%%~i"
                Call :OutIn "%%Name:%Pref%=%%" "%%~i" "%%~d\%%i"
        )
        Set "TName=:"
        FOR /F "usebackq tokens=1,2,3* delims=:" %%i IN (`2^>nul Sort /R "%Temp%\%~nx0.In"`) DO (
                Call :RenAll %%i %%j %%k %%l

        )
        2>nul Del "%Temp%\%~nx0.In"
Pause
Exit /B

:OutIn
        Set "Nall=%~2"
        Set "NN=%~1"
        Call Set "NN=%%Nall:%NN%=%%"
        >>"%Temp%\%~nx0.In" Echo %1:"%NN%":%2:%3
       
Exit /B

:RenAll
        If /I Not "%TName%"=="%~1" (
                Set "TName=%~1"
                Set "RName=%3"
        )
        If /I Not "%~nx4"==%RName% Echo Ren %4 %RName% &Ren %4 %RName%
Exit /B

CMD - Удаление префикса
Код:

@Echo Off
cls
        Set DAll="Z:\Box_In\Dir1" "Z:\Box_In\Dir2" "Z:\Box_In\Dir3" "D:\Май гад!"
        Set "Pref=0-"

        2>nul Del "%Temp%\%~nx0.In"
        FOR /D %%d IN (%DAll%) DO FOR /F "usebackq delims=" %%i IN (`2^>nul Dir "%%~d" /B /A:D`) DO (
                Set "Name=%%~i"
                Call :OutIn "%%Name:%Pref%=%%" "%%~i" "%%~d\%%i"
        )
        Set "TName=:"
        FOR /F "usebackq tokens=1,2,3* delims=:" %%i IN (`2^>nul Sort "%Temp%\%~nx0.In"`) DO (
                Call :RenAll %%i %%j %%k %%l

        )
        2>nul Del "%Temp%\%~nx0.In"
Pause
Exit /B

:OutIn
        Set "Nall=%~2"
        Set "NN=%~1"
        Call Set "NN=%%Nall:%NN%=%%"
        >>"%Temp%\%~nx0.In" Echo %1:"%NN%":%2:%3
       
Exit /B

:RenAll
        If /I Not "%TName%"=="%~1" (
                Set "TName=%~1"
                Set "RName=%3"
        )
        If /I Not "%~nx4"==%RName% Echo Ren %4 %RName% &Ren %4 %RName%
Exit /B

Коды отличаются только ключом сортировки /R в первом случае

NuclearBox 12-09-2020 19:13 2933807

Iska, megaloman, простите за отсутствие, уже не надеялся...
Огромное вам спасибо!
Полный восторг!
Тему закрываю - решена!


Время: 23:35.

Время: 23:35.
© OSzone.net 2001-