Компьютерный форум 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=308328)

c4uran 23-11-2015 11:50 2578007

сортировка файлов из папок
 
Задача простая:
есть корневая папка а в ней множество папок отличаются (кроме имени) они тем что в некоторых папках 1 файл а в некоторых больше 1
так вот
если в папке 1 файл то необходимо назвать его по имени папки в которой он лежит и переместить в корень(где лежат все эти папки)
если в папке больше 1 файла то необходимо его назвать по имени папки и имени этого файла(через точку) и так же переместить в корень

c4uran 24-11-2015 11:49 2578404

Похоже нужно на powershell, решение ниже не обрабатывает имена с ! знаками

Код:

@echo off
setlocal enableextensions enabledelayedexpansion
set "sDestFolder=D:\test"
set "ext=*.txt"

for /f "tokens=*" %%a in ('dir /B /AD %sDestFolder%') do call :action "%%a"

endlocal
exit

:action
set "sSourcePath=%sDestFolder%\%~1"
set "sCountFile="

for /r "%sSourcePath%" %%a in (%ext%) do set /a sCountFile+=1
for /r "%sSourcePath%" %%b in (%ext%) do call :rename "%%b" "%sCountFile%"

exit /b

:rename
:: Ввод: имя файла в директории в sDestFolder

set "sNewNamePart1=!sSourcePath:%sDestFolder%=!"

:: Определяет много файлов или один
if "%~2" LEQ "1" (
set "sNewName=!sNewNamePart1:~1,-1!%~x1"
) else (
set "sNewName=!sNewNamePart1:~1,-1!.%~nx1"
)

if not exist "%~dp1!sNewName!" (
        ren "%~1" "!sNewName!"
)
if not exist "%sDestFolder%\!sNewName!" (
        move "%~dp1!sNewName!" "%sDestFolder%"
)
exit /b


c4uran 07-12-2015 16:45 2582392

Правдами или не правдами написал такое решение, в довесок добавил очистку имен файлов от мусора

Логика примерно такая: Заходит в рабочую парку - выбирает директории из которых нужно достать файло - считает сколько там файлов если больше 1 то выполняет одну функцию если много то другую

в данном решение нет переноса файлов, только вывалит новые имена на экран что легко исправляется заменяя echo "moved $NewFileName > $WorkFolder" на перемещение (move) куда надо

так же хочу заметить что скрипт устойчив к сложным названиям папок и файлов

Код:

$WorkFolder = "D:\work"
[array]$Bad = "]" , "(" , ")" , " " , "_" , "-" , "&" , "}" , "{"

# Определяем папки в которых будет поиск
$TargetFolders = dir -Directory -Recurse -LiteralPath $WorkFolder

<# Данная функция вызывается для отчистки имени файла от мусора
# ->: Имя файла
# <-: Очищеное имя файла #>
function Clean-Name($NewfileName) {
            foreach ($B in $Bad) {
                    $NewfileName = $NewfileName.Replace($B,".")
            }
        $NewfileName = $NewfileName.Replace("[","")
        $NewfileName = $NewfileName.Replace("..",".")
        $NewfileName = $NewfileName.Replace("..",".")
   
Return $NewfileName
}

function LogFileInDirCount(){
Write-Host Total Files: $TotalFiles
Write-Host $Directory
}

function MoveFiles($NewFileName){
if (-not(Test-Path ($WorkFolder + $NewFileName) )) { echo "moved $NewFileName > $WorkFolder" } else { echo Error }
}

# Данная функция вызывается для работы с 1 нужным файлов в каталоге
# ->: путь к папке с файлами
function MultiFiles($Directory) {
LogFileInDirCount
$FilesInDir = dir -LiteralPath $Directory -file
    foreach ($File in $FilesInDir) {
          #если такого файла уже нет в корне
          if (-not($WorkFolder + "\" + $File.Name -eq $File.FullName)) {
                  #задаем имя файла без путя к корню ( но с папкой в корне и текущим именем файла )
                  $NewfileName = ($File.FullName.Replace($WorkFolder,"") | Split-Path -Parent) + " - " + $File.Name
                  #чистим имя файла от мусора
                  $NewfileName = Clean-Name $NewfileName.Replace("\","")
                  MoveFiles $NewfileName

          }
    }
}

# Данная функция вызывается для работы с больше чем 1 нужным файлов в каталоге
# ->: путь к папке с файлами
function SingleFile($Directory) {
LogFileInDirCount
$FilesInDir = dir -LiteralPath $Directory -file
    foreach ($File in $FilesInDir) {
          #если такого файла уже нет в корне
          if (-not($WorkFolder + "\" + $File.Name -eq $File.FullName)) {
                  #задаем имя файла без путя к корню ( но с именем папки и форматом файла)
                  $NewfileName = ($File.FullName.Replace($WorkFolder,"") | Split-Path -Parent) + " - " + $File.Extension
                  #чистим имя файла от мусора
                  $NewfileName = Clean-Name $NewfileName.Replace("\","")
                  MoveFiles $NewfileName
          }
    }
}

cls
# Считаем количество файлов в нужных директориях и выполняем
# функции в зависимости от количества нужных файлов в директориях
foreach ($Directory in $TargetFolders) {
   
    $Files = dir -LiteralPath $Directory.FullName -File -Include *.txt
    $TotalFiles = ($Files | Measure-Object).Count

    if ($TotalFiles -gt 1 ) { MultiFiles $Directory.FullName } else { SingleFile $Directory.FullName }
    Write-Host --------------------------
}



Время: 21:26.

Время: 21:26.
© OSzone.net 2001-