I want to write .bat file,
I have two folders which names are A and B.
I have pictures on A , and I want to transfer them from A to B in every 10 minutes,
But I want to transfer the last 20 pictures. Pictures names are 1.jpg 2.jpg ,,,,90.jpg
How can I do that? Is it possible?
thanks
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET "destdir=c:\destdir"
SET /a numbertomove=20
FOR /f "tokens=1*delims=:" %%a IN (
'dir /b /a-d /o-d "%sourcedir%\*.jpg"^|findstr /n "."'
) DO (
IF %%a leq %numbertomove% ECHO MOVE "%sourcedir%\%%b" "%destdir%\"
)
GOTO :EOF
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
Edited to remove self-scheduling.
to move the files you can use:
for /l %%i in (71,1,90) do move a\%%i.jpg b\%%i.jpg
For scheduling a task to run every 10 minutes see schtasks /create /?.
There are a lot of options, collect them to your needs.
It's a bit confusing to get the right syntax if you do it the first time, so you may have to ask a new question if you know, which options you want to use.
(NOTE: to use the forconstruct on commandline (not in batch) use single% instead of %%)
Related
I create a lot of hardlinks every week. When time comes to clean them, I find myself using the "DeleteAllHardlinks.bat" for ln (https://schinagl.priv.at/nt/ln/ln.html) but I have to drag and drop everyfile one after the other.
I would love to find a way to just select 100 files and drop them on the .bat, wait a while and find all those files and hardlinks deleted for good. Is there anyway to change the .bat file to allow this? (or maybe any other different method to acomplish the same?)
#echo off
REM
REM Check for commandline args
REM
if "[%~1]" == "[]" goto error
set LN=ln.exe
REM
REM List hardlink sibblings and delete all siblings
REM
for /f "delims=" %%a in ('#%LN% --list "%~1"') do (
del /f "%%a"
)
goto ausmausraus
:error
echo DeleteAllHardlinks: Argument is missing. Usage DeleteAllHardlinks ^<filename^>
echo e.g. DeleteAllHardlinks c:\data\myfile.txt
:ausmausraus
echo on
Thanks in advance!
Big thanks to Mofi!
The batch file could be very easily modified to support not just first argument, but all file name argument strings passed to the batch file by using one more for loop and %* as explained by call /?, i.e. use as replacement for the existing for loop:
for %%I in (%*) do for /F "delims=" %%J in ('ln.exe --list "%%~I" 2^>nul') do del /F "%%~J"
But the application starting the batch file has to pass each file name enclosed in double quotes to work properly.
Just using the for as offered in the comment solved the issue perfectly.
I have a folder called TEST. Inside there are 30 files.
Example:
DIM1_UPI_20170102.TXT
DIM2_UPI_20170908.TXT
DIM3_UPI_20180101.TXT
...
I have to rename them by removing the date tag
Exapmple:
DIM1_UPI.TXT
DIM2_UPI.TXT
DIM3_UPI.TXT
Can you please help me writing this in batch file?
Assuming your files are all starting with DIM
#echo off
setlocal enabledelayedexpansion
for /f %%i in ('dir "*.TXT" /b /a-d') do (
set "var=%%~ni"
echo ren !var!%%~xi !var:~0,-9!%%~xi
)
Once you can confirm that it does what you want, and ONLY then, remove the echofrom the last line to actually rename the files.
Important Note. If you have files with similar names, but different date entries, this will not work as you think. as Example:
DIM2_UPI_20170910.TXT
DIM2_UPI_20170908.TXT
The names are the same, but dates differ, making each filename Unique. If you rename them, there can be only 1 DIM2_UPI.TXT So as long as you understand this, you will be fine.
Edit: based on Amazon drive question. Note you need to change the directory portion to how you access amazon drive.
#echo off
setlocal enabledelayedexpansion
for /f %%i in ('dir "DIM*" /b /a-d') do (
set "var=%%~ni"
echo ren !var!%%~xi !var:~0,-16!%%~xi
)
I have hundreds of csv files . csv files are stored in folders and sub folders . I want to search fifty csv file whose file names have been determined , for example 1.csv , 2.csv , 3.csv , ... , 50.csv . very troublesome if I searched one by one using the Windows search tool . I would like if the files are found , save in the folder named FOUND . please help to overcome this problem by using the batch programming / bat ? thank you very much
There's a number of approaches one can take, depending on how much automation you require... To help you get started, you may want to look at this it helped me (and indeed continues to do so) when I started learning batch. Furthermore I will provide one possible template for achieving your objective, as I have interpreted it. Perhaps it is not the most elegant or efficient method, but it introduces a number of batch commands that you may or may not have encountered, which in turn may help you develop your own method.
#echo off
setlocal enabledelayedexpansion
echo Please enter a drive letter:
set /p "drive=>"
echo Please enter a search string:
set /p "searchstring=>"
echo %searchstring%>search.txt
set /p search=<search.txt
set /a suffix=0
echo.>>search.txt
:LOOP
for /f "tokens=*" %%i in ("search.txt") do (
set /a suffix=suffix+1
set seq=%search% !suffix!
echo !seq!>>search.txt
)
if !suffix! leq 49 goto LOOP
for /f "tokens=*" %%i in (search.txt) do (
for /f "tokens=*" %%j in ('dir /b /s /a-d %drive%:\"%%i.csv" 2^>nul') do (
if not exist "%~dp0\found" md "%~dp0\found"
move /y "%%j" "%~dp0\found\%%~nxj"
)
)
pause
This is not intended as a definitive solution, though you may find it answers your original query/request. All the best.
Here's another working solution for you..
#ECHO OFF
SETLOCAL EnableDelayedExpansion
REM First Set your directories input and output
SET InputDir=C:\Directory to your CSV files\
SET OutputDir=C:\Directory to your CSV files\FOUND
REM check if the FOUND directory exist, if not, then create it.
IF NOT EXIST OutputDir (
mkdir %OutputDir%
)
REM Grab a scan of the input directory and save it to a temporary file list.
Dir /a /b %InputDir%>"%OutputDir%\Found.txt"
REM Set the files you would like to find.
SET "File1=1.csv"
SET "File2=2.csv"
SET "File3=50.csv"
REM The loop, to process the matching file(s).
FOR %%A IN (%File1%,%File2%,%File3%) DO (
FOR /F "usebackq" %%B IN ("%OutputDir%\Found.txt") DO (
IF %%A==%%B (
copy "%InputDir%\%%A" "%OutputDir%\%%A"
)
)
)
REM Clean up the temp file list.
DEL "%OutputDir%\Found.txt"
Make note, I didn't add quotes to the Input and Output variables, but instead added quotes to the copy portion of the code to compensate for white spaces in your directory path. I tried to keep it simple, so you could follow the logic of how it processed what you are looking for, you can now modify this to your liking.. Have fun. Cheers!
Trying to figure out an efficient way to sort tv shows from download folder. I
know this is far from the best solution but it's within my comfort zone :)
Anyway, I want the batch file to search the file name and move it to the correct folder
My TV Show folder structure is TV > Show Name > Season > Files
So for example if I have a file named Archer.S01E01.mkv I'd like it moved to TV > Archer > Season 1 etc. I've created a couple variables %source% and %dest% to cut down the amount of space needed as shown below:
::Show: Archer
move %source%*archer*S01* %dest%archer\"season 1"\
move %source%*archer*S02* %dest%archer\"season 2"\
move %source%*archer*S03* %dest%archer\"season 3"\
move %source%*archer*S04* %dest%archer\"season 4"\
move %source%*archer*S05* %dest%archer\"season 5"\
move %source%*archer*S06* %dest%archer\"season 6"\
Is there a way to use an array to move the files to the correct folders? Something along the lines of:
move %source%*archer*S0[1-6]* %dest%archer\"season [1-6]"\ ?
I know that particular example won't work, I'm guessing I'll need some sort of loop? But for the life of me I have no idea how to make that work.
It would be even better if the loop would go through the files and match part of the string to the show so I wouldn't have to create a command for each and every tv show I have in my library.
Any ideas or help would be greatly appreciated!
Thanks
Assuming all files share the same template of "[ShowName].S[SeasonNumber]E[EpisodeNumber].mkv", then the following should create all folders as needed, and move the files. Please note - this is untested.
#echo off
set "source=yourSourceFolder"
set "dest=yourDestinationFolder"
pushd "%source%"
for /f "delims=" %%F in (
'dir /b /a-d *.mkv ^| findstr /rix "[^.]*\.s[0-9]*e[0-9]*\.mkv"'
) do for /f "tokens=1,2 delims=." %%A in ("%%F") do (
for /f "delims=SsEe0" %%S in ("%%B") do (
if not exist "%dest%\%%A\season %%S\" md "%dest%\%%A\season %%S\"
move "%%F" "%dest%\%%A\season %%S\" >nul
)
)
Another way (in place of season it will just create the subdirectorys SO1, SO2,...SO9 in the directory named with the SHOWNAME (Archer in your example) :
#echo off
SET "SOURCE=YOUR\SOURCE PATH"
SET "DEST=YOUR\DESTINATION PATH"
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "TOKENS=1,2* DELIMS=." %%A IN ('DIR /B/A-D "%SOURCE%\*.MKV"') DO (
SET $DEST=%%B
SET $DEST=!$DEST:~0,3!
IF NOT EXIST "%DEST%\%%A" MD "%DEST%\%%A"
IF NOT EXIST "%DEST%\%%A\!$DEST!" MD "%DEST%\%%A\!$DEST!"
MOVE "%SOURCE%\%%A.%%B.%%C" "%DEST%\%%A\!$DEST!"
)
The code below works fine, here is a list of it's functions:
It moves files based on the fist 4 characters to a pre-created folder with the same first 4 characters
If the folder does not exist, it will not move the file, as there is no folder with the same fist 4 chars.
#echo on
setlocal enabledelayedexpansion
cls
pushd R:\Contracts\Sites
for /f "tokens=*" %%1 in ('dir /a-d /b *') do (
set filename=%%1&set dirname=!filename:~0,4!
for /f "tokens=*" %%A in ('dir /ad /b') do (
set dirid=%%A & set dirid=!dirid:~0,4!
if "!dirid!" equ "!dirname!" move %%1 %%A
)
)
I would like to add one extra function to this code please. Pleas have a look at the example below.
I have 5 files
X32A-test.docx or X32A-test.pptx (there will only be one docx or pptx, "NEVER two with the same name")
X32A-test.pdf
X32A-test.avi
X32A-test-eng.sub
X32A-test-small.jpg
I would like the code to CREATE a folder if it does not exist, based on the file name if it has the extension docx or pptx.
So with the above example it would create a folder named: "X32A-test". Then all the other files with "X32A" in the front of the name will be moved to that newly created folder "X32A-test".
I hope it is clear enough. If not please ask me for more information.
Thank you
It is much simpler and more efficient to use the simple FOR instead of FOR /F in your case.
And rather than looping through every file and moving them individually, it is easier and more efficient to use wildcards.
The first loop finds the .pptx and .docx files and creates folders as needed
The second loop finds all the directories and moves all files that start with the directory name into the directory.
#echo on
setlocal enableDelayedExpansion
cls
pushd R:\Contracts\Sites
for %%F in (*.docx *.pptx) do (
set "folder=%%F"
2>nul md !folder:~0,4!
)
for /d %%F in (*) do move %%F* %%F
popd
If needed, you can protect yourself against directory names shorter than length 4.
#echo on
setlocal enableDelayedExpansion
cls
pushd R:\Contracts\Sites
for %%F in (*.docx *.pptx) do (
set "folder=%%F"
set folder=!folder:~0,4!
if !folder:~0,3! neq !folder! 2>nul md !folder!
)
for /d %%F in (????) do (
set "folder=%%F"
if "!folder:~0,3!" neq "%%F" move %%F* %%F
)
popd
Note that this solution may fail if a file name contains !. If that arises then you need to toggle delayed expansion on and off within the loop(s).
I can see the entire process (including the part already implemented) like this:
All the files that are not yet in their "home" directories are moved there.
For all .docx and .pptx files left, create directories based on the files' names.
Obviously, the step #2 creates new "homes" and those will still be "uninhabited" this far. So all that is left to do now is to repeat the step #1.
So I would probably reorganised your process and, with the additional requirement, it could be implemented this way:
…
PUSHD your_root_directory
FOR /D %%D IN (*) DO (
CALL :movefiles "%%D"
)
FOR %%F in (*.docx *.pptx) DO (
MKDIR "%%~dpnF"
CALL :movefiles "%%~dpnF"
)
…
GOTO :EOF
:movefiles
SET "dirname=%~n1"
SET "mask=%dirname:~0,4%*"
MOVE "%~dp1%mask%" %1
Note: The steps #2 and #3 could be either implemented as separate loops or combined in one. The above script uses the latter approach.
You can use negative offsets in the !var:~offset,len! evaluation as follows:
set fspec=X32A-test.docx
echo !fspec:~-10!
echo !fspec:~0,-10!
That second line above gives you -test.docx and you can simply check that against your two desired possibilities with an if statement (or two).
Then you can use the third line to get the rest of the name for creating a directory.
The following example script shows how this could be done:
#setlocal enableextensions enabledelayedexpansion
#echo off
set fspec=X32A-test.docx
set bit1=!fspec:~-10!
set bit2=!fspec:~0,-10!
if .!bit1!.==.-test.docx. echo mkdir !bit2!
if .!bit1!.==.-test.pptx. echo mkdir !bit2!
endlocal
I'm echoing the mkdir command rather than executing it so you need to take out the echo. You'll also need to integrate the set and if statements into your loop but, based on what you have so far, you should have little trouble with that.
If, as you seem to indicate in a comment, the first four characters are the key and the last five decide on whether to make the directory, as in:
x32s-test.docx
a21w-production.pptx
xxxx-whatever_the_blazes_you_want.some_other_rubbish.docx
Then you're really only interested in the first four and last five:
#setlocal enableextensions enabledelayedexpansion
#echo off
set fspec=a12b-whatever_the_blazes_you_want.some_other_rubbish.docx
set bit1=!fspec:~-5!
set bit2=!fspec:~0,4!
if .!bit1!.==..docx. echo mkdir !bit2!
if .!bit1!.==..pptx. echo mkdir !bit2!
endlocal
This checks the correct extensions and outputs:
mkdir a12b
as expected.