Batch script to move the files from source to destination based on the file name [duplicate] - batch-file

This question already has an answer here:
Variables are not behaving as expected
(1 answer)
Closed 21 days ago.
The detail requirement is I need to move files from source folder to Destination folder based on the File names. For example
ABC_TEST1.txt should be moved to Y:\Dest\ABC, EFG_TEST1.txt should be moved to Y:\Dest\EFG, XYZ.txt should be moved to Y:\Dest\Unkonow, GHI_TEST1.txt should be moved to Y:\Dest\Unkown.
I tried the script below.
setlocal EnableDelayedExpansion
for %%F in (*.txt) do (
set FileName=%%F
echo %%F
if x%FileName:_=%==x%FileName%(
for /F "tokens=1* delims=_" %%B in ("%%~nXF") do (
ren "%%F" "%%C"
if exist "Y:\Dest\%%B" (move "%%C" "Y:\Dest\%%B") else (move "%%C" "Y:\Dest\Unknown")
)
)else (move "%%C" "Y:\Dest\Unknown")
)
endlocal
If I add the if condition the script is not working, without the if condition it's working.
ABC_TEST1.txt should be moved to Y:\Dest\ABC, EFG_TEST1.txt should be moved to Y:\Dest\EFG
It's not moving the XYZ.txt, GHI_TEST1.txt to Y:\Dest\Unkonow.

Itemized adjustments
Remove the ren command since it's causing the script to fail.
Add an exist check inside the for loop to check if the destination folder exists.
If it exists it will move the files to that folder
If it does not it will move the files to the Unknown folder
This should move all .txt files in the current directory to the appropriate subfolder in the destination folder based on the prefix of the file name before the underscore.
Batch
setlocal EnableDelayedExpansion
for %%F in (*.txt) do (
set FileName=%%F
echo %%F
for /F "tokens=1* delims=_" %%B in ("%%~nXF") do (
if exist "Y:\Dest\%%B" (
move "%%F" "Y:\Dest\%%B"
) else (
move "%%F" "Y:\Dest\Unknown"
)
)
)
endlocal

Related

If zip file and folder name are identical, copy zip file into folder

I have many .zip files and folders some of them have identical names.
I will check zip file name and folder name if it is identical.
I will copy zip file into the folder and delete the zip file.
Is it possible to Automate the process?
I have found following code but couldn't edit it:
#echo off
setlocal EnableDelayedExpansion
pushd "C:\New folder"
FOR %%G IN (*.zip DO (
FOR /F "tokens=1 delims= " %%a IN ("%%G") do (
set "outFolder=%%a Random Center"
for /D %%i in (*.*) do (
for /F "tokens=1 delims= " %%b IN ("%%i") do (
if "%%a"=="%%b" set "outFolder=%%i"
)
)
if not exist "!outfolder!" md "!outfolder!"
move "%%G" "!outfolder!"
)
)
popd
pause
It creates Random Center folder and copy all the zip files in it which I don't want.
#echo off
setlocal
pushd "C:\New folder" || exit /b 1
for %%A in (*.zip) do if exist "%%~nA" (
pushd "%%~nA" && (
move /y "..\%%~nxA"
popd
)
)
popd
pause
Using move as see no need to
copy and del the zip file.
Argument /y will automatically
overwrite an existing file without
prompt.
Initial pushd changes the current directory
else exits with errorlevel 1.
The for loop iterates through each zip filename.
It checks if the name of the filename, without extension,
does exist, which is expected to be a folder.
If does exist, pushd into the directory, and then
move the zip file from the parent directory into
the current directory. popd will restore to the
previous directory.
Does final popd to restore to initial current directory.

Batch file to create folder and move file in the folder

I am in the middle of batch extracting screenshots for contents we are planning to use on a tube site I am working on.
The jpeg files per content is labled as followed:
6c82c0239f6eb839-1
6c82c0239f6eb839-2
all the way to 120
The file name is different per content
a82384e2c46ba4af-1
a82384e2c46ba4af-2
etc.
They will all be extracted to a singe folder.
So I basically need a batch file that will create folders based on the content name without the dash and number and move all 120 jpegs in the folder with the content name.
For example:
Create folder named 6c82c0239f6eb839 and
move 6c82c0239f6eb839-1 to 6c82c0239f6eb839-120 in to the created folder.
I saw another thread with the following batch file. its pretty much what I want but the folder name is only 3 characters long and the files are copied to the newly created folders instead of moving them.
#echo off
SetLocal EnableDelayedExpansion
for /F "delims=" %%a in ('dir /b *.jpeg') do (
set Name=%%a
set Folder=!Name:~0,3!
xcopy /y "%%a" !Folder!\
)
Could someone change this so that it will display full file name without the dash and number for the folders and move files in its respective folders instead of copy?
Thank you
#echo off
setlocal
#rem Get each jpeg file.
for /F "delims=" %%A in ('2^>nul dir /b *.jpeg') do (
rem Get filename as token before the dash.
for /f "delims=-" %%B in ("%%~A") do (
rem Make dir if needed.
if not exist "%%~B" md "%%~B"
rem Check if isdir.
2>nul pushd "%%~B" && popd
if errorlevel 1 (
>&2 echo Failed isdir "%%~B".
) else (
rem Do the move operation.
>nul move /y "%%~A" "%%~B"
if errorlevel 1 (
>&2 echo Failed move "%%~A" to "%%~B"
)
)
)
)
exit /b %errorlevel%
The code is well remarked so if you want to understand
the evaluated code by changing #echo off to #echo on.
The use of %errorlevel% after the exit /b is not
required though will let you know what the errorlevel is
when #echo on is used.
The pushd tests for a directory
(even if it is a symlink).
errorlevel is checked to decide if to echo a
error message or do the move.
As the for loop variables are used direct, use of
enabledelayedexpansion is not needed.
Many commands support the argument of /? to get help
about the command. i.e. move /?.
If you only try to copy the correct jpeg to the correct folder, you can do this:
#echo off
SetLocal EnableDelayedExpansion
CD <CORRECT ROOT PATH>
for /F "delims=" %%a in ('dir /b *.jpeg') do (
set Name=%%a
REM I presume all the files have 16 characters before the dash
set Folder=!Name:~0,16!
IF NOT EXIST !Folder! MKDIR !FOLDER!
xcopy /y "%%a" !Folder!\
)
I was not able to test.
First of all, I would like to apologize for my manners regarding my initial post.
The answer by micheal_heath has resolved my issue.
Furthermore, I happened to find this post by user Salmon Trout from a different site which also worked.
Batch file to make folders with part of file name and then copy files
#echo off
setlocal enabledelayedexpansion
for %%A in (*.psd *.jpg) do (
echo file found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "tokens=1* delims=_" %%D in ("!fname!") do set folname=%%D
echo folder name !folname!
if not exist "!folname!" (
echo Folder !folname! does not exist, creating
md "!folname!"
) else (
echo Folder !folname! exists
)
echo Moving file %%A to folder !folname!
move "%%A" "!folname!"
)
echo Finished
pause
I just changed the the following line remove the hypen and numbers to create folders for the file name properly.
for /f "tokens=1* delims=-***" %%D in ("!fname!") do set folname=%%D
I still lack the knowledge on why and how both methods work, but this has been an interesting start for me. I hope other beginners trying to solve a similar issue can find something useful from this post.

Batch Script to find a files inside all Sub Folders

I have the multiple images in sub folder, I don't know how many folders are there. I want to Batch script to find listed names in all the folders and copy the images to destination folder. I tried below script but am getting file not found error.
#echo off
rem Find files and copy files
setlocal EnableExtensions EnableDelayedExpansion
set "SourceBaseFolder=D:\System backup\picture batch file\Test\15oct2015"
set "TargetBaseFolder=C:\OutputFolder"
if not exist "%SourceBaseFolder%\*" (
echo %~nx0: There is no folder %SourceBaseFolder%
set "ErrorCount=1"
goto HaltOnError
)
cd /D "%SourceBaseFolder%"
if not exist "FileNames.txt" (
echo %~nx0: There is no file %SourceBaseFolder%\FileNames.txt
set "ErrorCount=1"
goto HaltOnError
)
set "ErrorCount=0"
for /F "usebackq delims=" %%N in ("FileNames.txt") do (
for /R %%J in ("%%N*") do (
set "FilePath=%%~dpJ"
if "!FilePath:%TargetBaseFolder%=!" == "!FilePath!" (
set "TargetPath=%TargetBaseFolder%\!FilePath:%SourceBaseFolder%\=!"
md "!TargetPath!" 2>nul
if exist "!TargetPath!\*" (
echo Copying file %%~fJ
copy /Y "%%~fJ" "!TargetPath!" >nul
) else (
set /A ErrorCount+=1
echo Failed to create directory !TargetPath!
)
)
)
)
:HaltOnError
if %ErrorCount% NEQ 0 (
echo.
pause
)
endlocal
Can any one fix this problem? Thanks in advance.
The solution you're trying to get to work seems excessively convoluted
I believe something similar to the following should do what you want
FOR /F %%G IN ('dir /a-d /s /b "D:\System backup\picture batch file\Test\15oct2015"^|findstr /I /E /G:"D:\System backup\picture batch file\Test\15oct2015\FileNames.txt"') DO (
copy "%%G" "C:\OutputFolder"
)
To ensure the filename matches are exact, all filenames in filenames.txt should be preceded by backslash, e.g.
\filename1.file
\filename2.file
You can easily generate such a file within a batch file, if necessary

Batch script that will insert filenames into files within multiple subfolders

I need help creating a batch script that will add the filename to the first line of every .csv within all subfolders. The batch file will be in the mainfolder. The same folder will contain several subfolders, each containing a large amount of .csv files. I need the files to stay within their respective folders. My goal is to add this to another working script I have that merges all files within a subfolder into a single .csv. This will provide a way to navigate through the merged file. I found some similar posts, but they weren't quite what I was looking for. This is the closest thing I could find but the delimiter stuff is throwing me off Batch file to Write Filename to first line
File Structure Example:
C:\MainFolder\batch_script.bat
C:\MainFolder\SubFolder1\csv1.csv
C:\MainFolder\SubFolder1\csv2.csv
C:\MainFolder\SubFolder2\csv3.csv
C:\MainFolder\SubFolder2\csv4.csv
File Contents before running script
csv1.csv:
This is the content of csv1.csv
csv2.csv:
This is the content of csv2.csv
csv3.csv:
This is the content of csv3.csv
csv4.csv:
This is the content of csv4.csv
File Contents after running script:
csv1.csv:
csv1.csv
This is the content of csv1.csv
csv2.csv:
csv2.csv
This is the content of csv2.csv
csv3.csv:
csv3.csv
This is the content of csv3.csv
csv4.csv:
csv4.csv
This is the content of csv4.csv
P.S.
I also found this code on another website but I'm not sure how I would make it loop through the different subfolders
FOR /F "usebackq tokens=1" %%i IN (`DIR /B`) DO (
ECHO %%i >> %1
TYPE %%i >> %1
)
#echo off
setlocal enableextensions disabledelayedexpansion
for /r %%a in (*.csv) do (
set /p "firstLine=" < "%%~fa"
setlocal enabledelayedexpansion
for /f "delims=" %%b in (".!firstLine!") do endlocal & if not "%%~b"==".%%~nxa" (
( echo %%~nxa
type "%%~fa"
) > "%%~fa.new"
move /y "%%~fa.new" "%%~fa" >nul
)
)
What it does is generate a new file with the name of the csv as the first line, appends the csv to the new file and moves the new file over the csv. In the process, it tests if the content of the first line is the same as the name of the csv to avoid reinclusion of the filename on each run of the batch file.
edited to adapt to comments - As the process will not be run more than once for set of csv files, the full code can be reduced to
#echo off
setlocal enableextensions disabledelayedexpansion
for /r %%a in (*.csv) do (
( echo %%~nxa
type "%%~fa"
) > "%%~fa.new"
move /y "%%~fa.new" "%%~fa" >nul
)
Try this:
for /r %%a in (*.csv) do (
copy /y "%%~a" "%temp%\%%~na"
Echo %%~na > "%%~a"
for /f "usebackq" %%b in ("%temp%\%%~na") do Echo %%b >> "%%~a"
del "%temp%\%%~na"
)
And that should do what you want it to. I would test it out first if you could.
This should create an all.csv in every folder in the tree under the C:\MainFolder and add the filename before the contents of each CSV file.
The filename will contain the full path but that can easily be changed if needed.
#echo off
for /d /r "C:\MainFolder\" %%a in (*) do (
pushd "%%a"
(for %%b in (*.csv) do (
echo %%b
type "%%b"
)
)>all.tmp
ren all.tmp all.csv
popd
)
pause

Batch script - concatenate sequential numbers on files to keep the names unique

I'm working on a script for copying files in a folder which corresponds to the file's name and I have that part worked out using a FOR loop which checks to make sure the destination folder exists and copies the files once it has verified that it does. Example: 11-01111_ABC_DEF.pdf would go into /11/0111/. The length may vary by one or two characters but the format is consistent. I've copied my basic script below.
My problem is that sometimes a file with the same name needs to be processed. How could I go about concatenating a number to the end of the file if one or more copies of the file already exists in the destination folder?
setlocal enableextensions enabledelayedexpansion
for %%x in (*.PDF *.TXT) do (
set "source="C:\files"
set "dest=R:\"
set "filename=%%x"
set "prefix=!filename:~0,2!"
set "folder=!filename:~3,5!"
if not exist !dest!\!prefix!\!folder! MOVE !filename! !source!\failed
if exist !source!\!filename! MOVE !filename! !dest!\!prefix!\!folder!
)
setlocal ENABLEDELAYEDEXPANSION
set "dest=worked"
for %%i in (*.pdf *.txt) do (
for /f "tokens=1-3* delims=-_." %%j in ("%%i") do (
if exist "%dest%\%%j\%%k" if exist "%dest%\%%j\%%k\%%i" if exist "%dest%\%%j\%%k\%%j-%%k-1_%%l_%%m" (
for /f "tokens=1-9* delims=-_." %%n in ('dir %dest%\%%j\%%k\%%j-%%k*-* /b') do set /a inc=%%p
set /a inc+=1
move "%%i" "%dest%\%%j\%%k\%%j-%%k-!inc!_%%l_%%m" || move "%%~i" "failed"
set inc=
)
if exist "%dest%\%%j\%%k\%%i" if not exist "%dest%\%%j\%%k\%%j-%%k-1_%%l_%%m" (
move "%%i" "%dest%\%%j\%%k\%%j-%%k-1_%%l_%%m" || move "%%~i" "failed"
)
if exist "%dest%\%%j\%%k" if not exist "%dest%\%%j\%%k\%%~i" (
move "%%~i" "%dest%\%%j\%%k\%%~i" || move "%%~i" "failed"
)
if not exist "%dest%\%%j\%%k" move "%%~i" "failed"
)
)
put this in the folder with the .txts and .pdfs comment if you want me to change something.

Resources