windows - Flyt filer til mapper baseret på deres navne

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har nogle filer i formularen:



filename1 1.ext
filename1 2.ext
filename1 3.ext
...
filename2 1.ext
filename2 100.ext
...
filename20 1.ext
filename20 15.ext
(etc.)



... hvor filename kan indeholde mellemrum.


Og jeg vil flytte dem til mappe filename1, filename2 mv.


Jeg ved, at jeg kan lave en for loop for \%\%i in (*.ext) do og fjerne forlængelsen med set folder=\%\%~ni. Så det, jeg mangler, er, hvordan man fjerner alt efter pladsen lige før nummeret og kun får filename1.


Jeg ved også, at jeg kan dele variabel folder, men i dette tilfælde ved jeg ikke ved hvilken karakter jeg skal dele, selvom jeg ved, at det vil være et mellemrum efterfulgt af et tal.


Så dybest set vil jeg have noget som dette:


@echo off
set folder=

for \%\%i in (*.ext) do set folder=\%\%~ni & set folder=getfoldernamefromvariablefoldersomehow & mv \%\%i \%folder\%

Bedste reference


@ECHO OFF
SETLOCAL
SET "sourcedir=U:sourcedir"

FOR /f "delims=" \%\%a IN (
 'dir /b /a-d "\%sourcedir\%*.ext" '
 ) DO (
 CALL :sub1 "\%\%a" \%\%a
)

GOTO :EOF

:sub1
SET "filename=\%~1"
:subloop
SHIFT
SET "numname=\%~1"
IF NOT "\%~2"=="" GOTO subloop
CALL SET "dirname=\%\%filename: \%numname\%=\%\%
ECHO( MD "\%sourcedir\%\%dirname\%" 2>nul
ECHO( MOVE "\%sourcedir\%\%filename\%" "\%sourcedir\%\%dirname\%\%numname\%"
GOTO :eof


Du skal ændre indstillingen for sourcedir for at passe dine forhold.


De nødvendige MD-kommandoer er kun ECHO ed til testformål. Når du har bekræftet, at kommandoerne er korrekte , skal du ændre ECHO(MD til MD for at oprette katalogerne.


De nødvendige MOVE-kommandoer er kun ECHO ed til forsøgsformål. Når du har verificeret, at kommandoerne er korrekte , skal du ændre ECHO(MOVE til MOVE for at flytte filerne. Tilføj >nul for at undertrykke rapportmeddelelser (f.eks. [[1 file moved)


Udfør en katalogliste over de nødvendige filer i grundformularen uden katalognavne. Send det fulde fulename i citater og uden underrutinen sub1.


I underrutinen skal du gemme kildefilen i filename og derefter skifte hver parameter, der leveres, indtil der ikke er nogen anden parameter; værdien i numname skal så være det sidste eller krævede filnavn.


Fjern numname med et ledende rum fra filename for at få det nødvendige undermappe, lav det undermappe og flyt filen.


[[rediger i lyset af kommentar]]


@ECHO OFF
SETLOCAL
SET "sourcedir=U:sourcedir"

FOR /f "delims=" \%\%a IN (
 'dir /b /a-d "\%sourcedir\%*.ext" '
 ) DO (
 CALL :sub1 "\%\%a" \%\%a
)

GOTO :EOF

:sub1
SET "filename=\%~1"
SET "destdirname=\%~2"
:subloop
SHIFT
SET "numname=\%~1"
IF NOT "\%~2"=="" GOTO subloop
CALL SET "dirname=\%\%filename: \%numname\%=\%\%
ECHO( MD "\%sourcedir\%\%destdirname\%" 2>nul
ECHO( MOVE "\%sourcedir\%\%filename\%" "\%sourcedir\%\%destdirname\%\%numname\%"
GOTO :eof


Det er svært at skribe dine hensigter, når du ikke giver noget eksempel.


destdirname er indstillet til den anden parameter ved indtastning af sub1, som vil være den første gruppe af tegn inden det første rum.


md behøver ikke at blive lukket, da 2>nul vil undertrykke fejlmeddelelsen directory exists.

Andre referencer 1




Her er et script, der gør hvad du vil. Den spalter det sidste SPACE efterfulgt af tal fra filnavnet og bruger den resterende streng som navnet på bevægelses destinationskatalog.


Denne fremgangsmåde håndterer alle gyldige tegn for filnavne korrekt, selv ^, &, \%, !, ( og ). Det kan endda håndtere filnavne, der indeholder SPACE plus tal plus .ext igen korrekt.


Så her er koden:


@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "\_SOURCE=."
set "\_TARGET=."

for /F "eol=| delims=" \%\%F in ('
    dir /B "\%\_SOURCE\%*.ext" ^| findstr /R /I /C:" [0123456789][0123456789]*.ext$"
') do (
    set "FILE=\%\%F"
    call :SPLIT LAST REST "\%\%F"
    setlocal EnableDelayedExpansion
    2> nul mkdir "!\_TARGET!!REST!"
    ECHO move /Y "!\_SOURCE!!FILE!" "!\_TARGET!!REST!"
    endlocal
)

endlocal
exit /B


:SPLIT  rtn\_last  rtn\_rest  val\_string
    setlocal DisableDelayedExpansion
    set "RES=" & set "STR=\%~3"
    :LOOP
    for /F "tokens=1,* delims= " \%\%I in ("\%STR\%") do (
        if "\%\%J"=="" (
            set "RES=\%\%I"
        ) else (
            set "STR=\%\%J"
            goto :LOOP
        )
    )
    set "STR=\%~3|"
    call set "STR=\%\%STR: \%RES\%|=\%\%"
    (
        endlocal
        set "\%~1=\%RES\%"
        set "\%~2=\%STR:^^=^\%"
    )
    exit /B


Efter at have testet scriptet fjerner du kommandoen ECHO for at flytte filer. Medmindre du fjerner indstillingen /Y fra kommandoen move, overskrives filer uden at blive bedt om det. For at undertrykke summariske meddelelser (som 1 file(s) moved.), tilføj > nul til kommandolinjen move. Bemærk at enhver prompt også var skjult, såfremt du fjernede indstillingen /Y.

Andre referencer 2


Tak til alle jer for dine kommentarer. Endelig var jeg i stand til at få en løsning:


@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "\_source=C:Userskurok\_000Downloads"
set "\_target=C:Userskurok\_000YandexDiskMangas"

for /f "eol=| delims=" \%\%f in ('dir /b "\%\_source\%*.7z"') do (  
    call :fixNames "\%\%f" \%\_source\%
)

for /f "eol=| delims=" \%\%f in ('dir /b "\%\_source\%*.7z" ^| findstr /r /i /c:" [0123456789][0123456789]*.7z$"') do (
    set "file=\%\%f"
    call :split last rest "\%\%f"
    setlocal EnableDelayedExpansion
    2> nul mkdir "!\_target!!rest!"
    move /y "!\_source!!file!" "!\_target!!rest!" >nul
    echo moved \%\%f to !\_target!!rest!
    endlocal
)
endlocal
exit /b

:split  rtn\_last  rtn\_rest  val\_string
setlocal DisableDelayedExpansion
set "res=" & set "str=\%~3"
:loop
for /f "tokens=1,* delims= " \%\%i in ("\%str\%") do (
    if "\%\%j"=="" (
        set "res=\%\%i"
    ) else (
        set "str=\%\%j"
        goto :loop
    )
)
:quit
set "str=\%~3|"
call set "str=\%\%str: \%res\%|=\%\%"
(
    endlocal
    set "\%~1=\%res\%"
    set "\%~2=\%str:^^=^\%"
)
exit /b

:fixNames \_file \_folder
@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "FILE=\%1"
set "FILE=\%file:~1,-1\%"
set "folder=\%2"

for /F "tokens=1,* delims=0123456789" \%\%A in ("\%FILE\%") do (
    set filename=!FILE:\%\%B=!\%\%~xB
    )
if not "\%filename\%"=="\%FILE\%" (rename "!folder!!FILE!" "!filename!")