Seleziona casualmente il file, rinomina, sposta in una nuova directory


1

Abbiamo una directory che viene caricata con oltre 40 file con nomi di file diversi. Iniziano tutti con la stessa struttura del nome del file, ma una data viene aggiunta alla fine.

Esempio:

FILE.txt.01012013
FILE.txt.01022013
FILE.txt.01032013

Ho bisogno di creare un file batch che faccia alcune cose complesse e alcune non così complesse:

  1. seleziona solo un file.
  2. Rinominare il file con un altro nome. (Esempio: TEST.txt) Nota: il nome del file rinominato sarà sempre TEST.txt)
  3. Sposta il file rinominato dalla sua attuale directory a un nuovo directory.
  4. 15 minuti dopo ... ricominciare dal punto 1. (Nota: questo deve continuare a correre fino a quando non ci sono più file nell'originale directory.)

Quello che ho provato: il mio livello di abilità sui file batch è molto semplice, e quindi ho cercato di cercare sul web suggerimenti. Posso trovare il codice per rinominare un file (ma devi specificare il nome del file originale). Posso trovare il codice per trovare un file usando un * nel nome del file, ma penserei che selezioni tutti i file nella directory. Ho bisogno che succeda un file alla volta e ogni 15 minuti. Una volta che un file è stato rinominato e spostato nella nuova directory ... Esiste un processo di watcher di file che prende quel file (in questo esempio TEST.txt) e ingerisce i dati. Una volta che i dati sono ingeriti, il file viene eliminato. Ciò significa che quando il file successivo viene rinominato in TEST.txt e spostato nella directory non ci sarà alcun motivo per sovrascrivere il file precedente.


1
Benvenuto al superutente Puoi dirci cosa hai già provato? Di modificare nel tuo post per fare una domanda, migliori le tue possibilità di ottenere una risposta dettagliata. Anche pubblicare il codice che hai già iniziato e aggiungere qualsiasi dettaglio, come il sistema operativo con cui questo sarà usato, sarebbe molto utile.
CharlieRB

Ho aggiunto più dettagli, ma sfortunatamente non penso che possa essere di grande aiuto.
JP Hooks

Risposte:


0

Questo sembra quello che vuoi, tuttavia è necessario colmare le lacune.

set count=0
for /f %%i in (file_path\*.*) do set /a count+=1
set test=%count%
:loop
if %test% neq %count% timeout /nobreak 900 >nul
set /a num=%random% %% %count% + 1
set /a count-=1
if %count% leq 0 goto end
for /f "skip=%num%" %%i in (file_path\*.*) do (
    ren %%i TEST.txt
    move TEST.txt file_path\
    goto loop
)
:end

Cosa fa:

  1. Scopri quanti file in una cartella (che devi modificare).
  2. Crea un numero casuale con il numero massimo di file nella cartella.
  3. Prendine una dal numero massimo, per la prossima volta.
  4. Salta una quantità casuale di file (designati dal numero casuale) e scegli quello successivo.
  5. Rinominare il file in TEXT.txt e spostarlo in percorso_file \ (che è necessario modificare).
  6. Attendere 15 minuti (900 secondi).

Spero che sia d'aiuto.

Nota, è necessario modificare ** percorso_file ** nei file appropriati.


Questo non funzionerà, poiché / f non legge le directory così. Uso dir comando o un ciclo for semplice senza qualificatore.
Endoro

Cosa fa "skip" fare dentro for /f "skip=%num%" %%i in (... ?
Kevin Fegan

@KevinFegan Era pensato per saltare una certa quantità di file e scegliere quello successivo. Questo era fondamentalmente la scelta di un file casuale.
Prof Pickle

@Endoro L'OP ha detto che a caso file doveva essere scelto. Tuttavia, hai ragione.
Prof Pickle

Penso quando l'OP ha detto Randomly stavano parlando di trovare un file in cui il nome completo non è conosciuto prima del tempo (qualcosa del genere Randomly named ). Non penso che stessero parlando dell'ordine in cui i file vengono elaborati. Speriamo che il PO chiarisca questo.
Kevin Fegan

0

Prova questo, fa tutto quello che hai chiesto:

@echo off&setlocal enabledelayedexpansion
set "startfolder=folder1"
set "targetfolder=folder2"

cd /d "%startfolder%"
:randomstart
set /a filecnt=0
for %%i in (*) do set /a filecnt+=1
if %filecnt% equ 0 echo(no file found in %Startfolder%&goto:eof
set /a rd=(%random%%%%filecnt%)+1
set /a cnt=0
for %%i in (*) do set /a cnt+=1&if "!cnt!" equ "%rd%" set "randomfile=%%~i"
echo "%randomfile%"
move "%randomfile%" "%targetfolder%\test.txt"
ping -n 900 localhost >nul
goto:randomstart

-1

Ecco un semplice script batch per elaborare i file:

@echo off

rem     set your file-match pattern here. Could be *.* for all files, or whatever you wish.
set "zzmatchpattern=FILE.txt.*"

rem     set filename for renamed files
set "zzfinalname=TEST.txt"

rem     set source folder here
set "zzsourcepath=C:\source\"

rem     set destination folder here
set "zzdestpath=C:\dest\"

rem     set your loop delay here
set "zzdelayminutes=15"

rem     **********************************
rem     might be good to add some error checking here
rem     **********************************


:start
rem:start
set /a zzdelayseconds=zzdelayminutes*60


:restart
rem:restart

for %%f in ("%zzsourcepath%%zzmatchpattern%") do call :work "%%~f"

timeout /t %zzdelayseconds%
goto :restart


:work
rem:work

set "zz_w1=%~1"
echo.
echo Renaming file "%zz_w1%" to "%zzfinalname%"
ren "%zz_w1%" "%zzfinalname%">nul 2>&1

echo Moving file: "%zzsourcepath%%zzfinalname%" to "%zzdestpath%"
move "%zzsourcepath%%zzfinalname%" "%zzdestpath%">nul 2>&1

timeout /t %zzdelayseconds%

rem     Go get next file, if any.
goto :EOF



Se si desidera una soluzione più completa, lo script batch di seguito include:

  • Convalida abbastanza completa (controllo degli errori) dei valori di input.
  • Con una semplice modifica, è possibile inserire i valori in modo sicuro dalla riga di comando.
  • All'inizio, controlla se il file di destinazione esistente è presente e attende che il processo esterno rimuova il file.
  • Controlli e rapporti sulle operazioni di ridenominazione e spostamento non riuscite.
  • Riprendi dopo i file processi di cessazione / interruzione rinominati ma non spostati.
  • Permette il ritardo richiesto (opzionale) (Choice.exe) che consente "Continua ora" e il grazioso "Esci".


@echo off

rem     set your file-match pattern here. Could be *.* for all files, or whatever you wish.
set "zzmatchpattern=FILE.txt.*"

rem     set filename for renamed files
set "zzfinalname=TEST.txt"

rem     set source folder here
set "zzsourcepath=C:\source"

rem     set destination folder here
set "zzdestpath=C:\dest"

rem     set your loop delay here
set "zzdelayminutes=15"

rem     select  Prompted-delay, or simple Timeout-delay. P=Prompted, otherwise simple Timeout
rem     For Prompted-delay "Choice.exe" must be present on the computer.
set "zzdelaytype=T"


rem     **********************************
rem     error checking
rem     **********************************


:checksourcepath
rem:checksourcepath

rem     insure source path is valid (exists), and has trailing slash
if "%zzsourcepath%."=="." goto :sourcepatherror
set zzt1=%zzsourcepath:~-1,1%
if not "%zzt1%."=="\." set "zzsourcepath=%zzsourcepath%\"
if not exist "%zzsourcepath%*.*" goto :sourcepatherror
goto :checkdestpath


:sourcepatherror
rem:sourcepatherror

echo.
echo Error processing source path: [%zzsourcepath%].
echo.
call :cleanexit
exit /b 1


:checkdestpath
rem:checkdestpath

rem     insure dest path is valid (exists), and has trailing slash
if "%zzdestpath%."=="." goto :destpatherror
set zzt1=%zzdestpath:~-1,1%
if not "%zzt1%."=="\." set "zzdestpath=%zzdestpath%\"
if not exist "%zzdestpath%*.*" goto :createdestpath
goto :checkname


:createdestpath
rem:createdestpath

md "%zzdestpath%" >nul 2>&1
if not exist "%zzdestpath%*.*" goto :destpatherror
goto :checkname


:destpatherror
rem:destpatherror

echo.
echo Error processing destination path: [%zzdestpath%].
echo.
call :cleanexit
exit /b 2


:checkname
rem:checkname

if "%zzfinalname%."=="." goto :nameerror
goto :checkdelayminutes


:nameerror
rem:nameerror

echo.
echo Error: Rename target filename cannot be empty.
echo.
call :cleanexit
exit /b 3


:checkdelayminutes
rem:checkdelayminutes

set zzt1=0
set zzt2=1
set /a zzt1=zzt2*zzdelayminutes
if "%zzt1%."=="." goto :minute1serror
if %zzt1% LEQ 0 goto :minutes1error
if %zzt1% GEQ 1441 goto :minutes2error
goto :checkpattern


:minutes1error
rem:minutes1error

echo.
echo Error: Minutes must be a number greater than 0.
echo.
call :cleanexit
exit /b 4


:minutes2error
rem:minutes2error

echo.
echo Error: Minutes must be a number not greater than 1440 (1 day).
echo.
call :cleanexit
exit /b 5


:checkpattern
rem:checkpattern

rem     pattern must have at least 1 "*"
if "%zzmatchpattern%."=="." goto :patternerror
echo "%zzmatchpattern%"|find "*">nul
if %errorlevel% EQU 0 goto :start
rem goto :patternerror


:patternerror
rem:patternerror

echo.
echo Error: Pattern cannot be empty, and must contain at least 1 "*".
echo.
call :cleanexit
exit /b 6


:start
rem:start
set /a zzdelayseconds=zzdelayminutes*60
set /a zzpartialdelay=zzdelayseconds/3
set zzexiting=0


:restart
rem:restart

rem     if destination file already exists, wait a bit more

if not exist "%zzdestpath%%zzfinalname%" goto:checkaborted

call :waitexternal
if %zzexiting% NEQ 0 exit /b %zzexiting%
goto :restart


:checkaborted
rem:checkaborted

if not exist "%zzsourcepath%%zzfinalname%" goto :work1
echo.
echo Completing previously started file move.
echo Moving file: "%zzsourcepath%%zzfinalname%" to "%zzdestpath%"
move "%zzsourcepath%%zzfinalname%" "%zzdestpath%">nul 2>&1
goto :restart


:work1
rem:work1

set zzdelayflag=1
set zzsuccess=0
for %%f in ("%zzsourcepath%%zzmatchpattern%") do call :work2 "%%~f"

if %zzexiting% NEQ 0 exit /b %zzexiting%

echo %zzsuccess% file(s) processed.

if %zzdelayflag% EQU 0 goto :checksuccess
call :dodelay %zzdelayseconds%
if %zzexiting% NEQ 0 exit /b %zzexiting%
goto :restart


:checksuccess
rem:checksuccess

if %zzsuccess% NEQ 0 goto :restart

echo.
echo Failed to rename all existing files, exiting.
call :cleanexit
set zzexiting=7
exit /b %zzexiting%
goto :EOF


:work2
rem:work2

if %zzexiting% NEQ 0 exit /b %zzexiting%

set "zz_w1=%~1"
set zzdelayflag=0
echo.
echo Renaming file "%zz_w1%" to "%zzfinalname%"
ren "%zz_w1%" "%zzfinalname%">nul 2>&1
if exist "%zz_w1%" goto :renameerror
if not exist "%zzsourcepath%%zzfinalname%" goto :renameerror
goto :movefinalfile


:renameerror
rem:renameerror

echo Error: Failed to rename file "%zz_w1%" to "%zzfinalname%"
echo.

rem     Rename failed, skip it and get next file (immediately), if any.
goto :EOF


:movefinalfile
rem:movefinalfile

rem Rename success, move the file

if not exist "%zzdestpath%%zzfinalname%" goto :domove

call :waitexternal
if %zzexiting% NEQ 0 exit /b %zzexiting%
goto :movefinalfile


:domove
rem:domove

echo Moving file: "%zzsourcepath%%zzfinalname%" to "%zzdestpath%"
move "%zzsourcepath%%zzfinalname%" "%zzdestpath%">nul 2>&1
if exist "%zzsourcepath%%zzfinalname%" goto :moveerror
goto :movecomplete


:moveerror
rem:moveerror

echo Error: Failed to move file "%zz_w1%" to "%zzdestpath%%zzfinalname%"

rem     Move failed, restore (un-rename) file and skip it and get next file (immediately), if any.

for %%g in ("%zz_w1%") do set "zzt1=%%~nxg"
echo Restore file: "%zzsourcepath%%zzfinalname%" to "%zzt1%"
ren "%zzsourcepath%%zzfinalname%" "%zzt1%">nul 2>&1
echo.

goto :EOF


:movecomplete
rem:movecomplete

set /a zzsuccess+=1
call :dodelay %zzdelayseconds%
if %zzexiting% NEQ 0 exit /b %zzexiting%
rem echo.

rem     Go get next file, if any.
goto :EOF


:dodelay
rem:dodelay

set zztime=%1

if /I "%zzdelaytype%."=="P." goto :dopauseddelay

echo.
timeout /t %zztime%
goto :EOF


:dopauseddelay
rem:dopauseddelay

echo.
echo Waiting (%zztime% seconds) to process next file... You can wait to 
echo continue after delay or Q(uit) or C(ontinue) now.
choice /c cq /n /t %zztime% /d c /m "Press Q(uit) or C(ontinue now) or No Action (wait) to continue after delay. "
if %errorlevel% EQU 1 goto :EOF

echo.
echo User selected Q(uit), exiting.
call :cleanexit
set zzexiting=254
exit /b %zzexiting%
goto :EOF


:waitexternal
rem:waitexternal

echo.
echo Waiting for externl process...
call :dodelay %zzpartialdelay%
if %zzexiting% NEQ 0 exit /b %zzexiting%

goto :EOF


:cleanexit
rem:cleanexit

set "zzdelayflag="
set "zzdelayminutes="
set "zzdelayseconds="
set "zzdelaytype="
set "zzdestpath="
set "zzexiting="
set "zzfinalname="
set "zzmatchpattern="
set "zzpartialdelay="
set "zzsourcepath="
set "zzsuccess="
set "zzt1="
set "zzt2="
set "zztime="
set "zz_w1="

goto :EOF

Se hai bisogno di qualcosa di questo modificato o spiegato, fammelo sapere.


1
Mi chiedo che cosa fosse il downvote per ...?
Prof Pickle

@ProfPickle - +1 per il commento perfetto - grazie, mi stavo chiedendo anch'io. Se lo sapessi, forse potrei sistemarlo ... ma così com'è ora, non ne ho idea. Oh bene, alcuni alti, alcuni bassi ... tutto in media.
Kevin Fegan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.