I want to move all files in some folders to a newly created folder in that same folder. For easier understanding, see the example below (the input is shown left, output is shown right):
C:\1\A\file1.tif C:\1\A\Named\file1.tif
file2.tif file2.tif
file3.tif ==> file3.tif
C:\1\B\file1.tif C:\1\B\Named\file1.tif
file2.tif file2.tif
file3.tif file3.tif
In the example above, I have only shown the first three files in every folder, but the total number may vary (usually there are 1000 files per folder). Also, I have only shown two folders (A and B), but the total number of folders may vary as well (usually about 10 folders). Finally, I have only shown the folder '1', but the number of these kind of folders may also vary (usually '1' through '10'). So I was looking to a script that could do these actions independent of the number of files or folders, and independent of the names of the folders/files (I chose '1', 'A' and 'file1.tif' only as examples).
The idea is that, now, I have to manually create empty folders (called 'Named' in the example above) in each folder ('A' and 'B' in the example above) where the files are. Then I have to manually move all the files into that newly created folder 'Named'. I have to do this for all folders (about 100). I can do this entire process manually if I had to do it only once, but the thing is that I have to do this process many times :-). So automating this would save a lot of time.
Does anyone know a script that can do this? Thanks a lot!
tested a little, this might work, in a command file
make a cmd file with these lines
for /r %%a in (*.*) do call :singlecopy %%a
goto :eof
:singlecopy
set src=%~p1
set dst=%~p1NAMED
set file=%~n1%~x1
rem replace NAMED in src with nothing
set srctst=%src:NAMED=%
rem if src and srctst are still the same, copy
if %srctst%==%src% robocopy %src% %dst% %file% /move /create
goto :eof
After thorough testing, this works great. However, as it is a lot of files, you may want to set up a little test environment, like in your example, to use this on first, before you use it on your actual data.
setlocal enabledelayedexpansion
cd C:\rootfolder
for /f "tokens=*" %%a in ('dir /s /b /a:d') do (
attrib "%%a\*.*" | find "File not found"
if !errorlevel!==1 (
if not exist "%%a\Named" md "%%a\Named"
xcopy "%%a\*.*" "%%a\Named"
del "%%a\*.*" /f /q
)
)
Related
So I have a lot of folders(1000+) and I want to add an incrementing number at the start of each one of them. The folder names contain spaces. I am on windows 10.
Example of folder names:
Folder number-one
Folder number-two
Folder number-three
Output wanted:
1000_Folder number-one
1001_Folder number-two
1002_Folder number-three
I've looked for similar articles but I didn't find something for my particular case.
The following code will rename all folders in c:\flrtest beginning with the letter "f" to an incremented number beginning with 1000.
I wrote it with the "f" restriction for two reasons:
(1) in case there were folders you did not want to change. To change all folders in c:\flrtest then just change line 3 from "c:\flrtest\f*" to "c:\flrtest"
(2) Allows running the script more than once without ill effect. If the "f" restriction is removed and the script is run more than once over the same set of directories it will yield results you probably don't want. The directories will end up with names such as "1000_1000_folderA" etc.
Since your folder will likely be somewhere other than "c:\flrtest" then just change this location in lines 3 & 7.
Hopefully this helps.
#echo off
set inc=1000
for /f "delims=" %%i in ('dir /a:d /b "c:\flrtest\f*"') do call :RenDir "%%i"
exit /b
:RenDir
ren "c:\flrtest\%~1" "%inc%_%~1"
set /a inc=inc+1
exit /b
Before running
After running
Removing the "f" restriction and running twice. Not so good.
Before I start posting code I am wondering if this is even feasible.
I have a directory of folders I need to move to a new directory.
But I only need to move the folders that contain only 2 files in them.
The rest of the folders have more than 2 files in them, but they need to stay.
So would this be feasible with a batch file?
This was interesting so I took a stab at it:
#echo off
set "dir=C:\Your\Current\Directory"
set "ndir=C:\Your\New\Directory"
setlocal enabledelayedexpansion
for /d %%A in (%dir%\*) do (
pushd "%%A"
for /f %%B in ('dir /a-d-s-h /b ^| find /v /c ""') do (
set cnt=%%B
if "!cnt!" == "2" (if not exist "%ndir%\%%~nA" robocopy "%%A" "%ndir%\%%~nA" /e)
)
)
pause
I kept running into issues so I modified a few things to make it do what I wanted; there're likely more elegant ways to go about it, but this worked ¯\_(ツ)_/¯. First thing is setting variables for your current directory (dir) and your new directory (ndir) to make it a little easier to digest later on; we also need to enable delayed expansion since the value of our counting variable (cnt) will change between loop iterations. The first FOR loop is /d, which will loop through folders - we set each of those folders as parameter %%A and use that to change our directory (using pushd) prior to running our nested commands.
The second FOR loop is /f, which will loop through command results - the commands in this case being dir and find. For dir we are specifying /a to show all files that -d aren't folders, -s system files, or -h hidden files, and we display that output in /b bare format. Using the output from dir, we run find and specify to /v display all non-empty lines and then /c count the number - which becomes parameter %%B.
Finally, we set %%B as our counting variable (cnt) - if !cnt! is equal to 2, we see if the folder already exists in the new directory, and if it does not we robocopy it over. The move command was giving me some trouble because the folder would be locked by the loop, so if you want you could also throw in a DEL command to delete the original folder.
Let me know if that helps! Hopefully your research was going well anyway.
References: Counting Files, FOR Looping, pushd, DIR, FIND, robocopy
I am still a beginner to batch scripting so I would appreciate more explanation than usual to help me if at all possible.
Purpose:
I wrote this script to try to move files based on whether they have a folder's name within their name. For example, I have a folder named "cow" and a file named "cow_5234.txt", the file would be moved into the folder. The purpose of this is to move files with company names to a company folder from a messy folder full of files so I don't think a file going to the wrong folder will be much of a problem.
Problem:
The problem I am having is that many of the files that are supposed to be transferred to folders are being misplaced. I have around 3000 files in a folder along with 300 folders and this script. After I run it, only around 100 files get placed into the correct folders, while 900 are left behind (because they don't have a folder name within them) while the rest just disappear.
What I have tried to do:
I have gone through and checked the original list of folder names, which is all correct. Then I modified the script to output the filename to a .txt file instead of move it. Instead of getting a reasonable amount of files, there are 4000 files (I checked the line count). Some of these files don't have a folder name in them. I then took a subset of around 200 files and 20 folders and ran the script with them. For some reason, only 80 files remained, 1 was placed into a folder, although it didn't have a single similar character as the folder, and the rest just disappeared. I'm not sure what is happening at all. Here is the code:
#echo off
dir /a:d /b > list.txt
for /F %%i in (list.txt) do call :process %%i
goto :eof
:process
set "search=%1"
for /f "eol=: delims=" %%F in ('dir /A:-D /b^|find "%search%"') do move /Y "%%F" "%search%"
goto :eof
Edit 1:
As recommended in the comments, I have added a "goto :eof" to the end of the block of code, however, the problem still remains.
Edit 2:
I didn't add a "goto :eof" to the end of the main function. Thanks for clarifying!
So, this is a particularly puzzling problem for me. I'm open to using whatever I must, but I typically only write simple batch files.
I have a huge research project at the hospital where I work, and the data I'm working with is presented to me with a 4 digit subject identifier followed by a timestamp, as seen in this example:
6443_20170419_141200416
6443_20170419_141200447
6443_20170419_141200500
6476_20170419_141200537
6476_20170419_141201112
etc.
I have literally thousands of these folders, and in each of them is between 1 and 3 files with very long file names - the only commonality is the .DCM extension.
What I'd like to do is have a script that will extract the first 4 characters of the folder name, create a new directory with that 4 character name, and then copy any files located within folders with the matching prefix into the newly created folder.
For example, let's say the folders which all start with 6443 have several .DCM files in them. I want to create a new folder named 6443 (in a different location that the then current directory, to avoid accidental deletion), and then move all of the .DCM files from each directory into the new folder.
I have a .TXT file which contains all of the subject ID #'s that I've been using for various other scripted tasks, using FOR /F to walk this file, if that gives anyone an idea for a solution.
This once is really picklin' my noggin. Help!!!
----- ADDITIONAL INFO -----
I've been making progress, but it's still not right. I'm using the script as shown below, but it's moving ALL of the files in each of the folders to each of the newly created folders, instead of sorting them by 4 digit prefix.
#ECHO on
cls
FOR /f "delims=_" %%a IN ('dir /b /ad "*_*_*"') DO (
if not exist %%a MD .\combined\%%a
FOR /d /r %%d IN ("*") DO (
copy %%d\* .\combined\%%a\*
)
)
Here is the corrected script:
#echo on
cls
for /F "tokens=1* delims=_" %%a in ('dir /B /A:D "????_*"') do (
if not exist ".\combined\%%a\" md ".\combined\%%a"
copy ".\%%a_%%b\*.dcm" ".\combined\%%a"
)
What I changed:
the tokens option has been added to the outer for /F loop in order to be able to rebuild the original source directory name later;
the directory search pattern has been improved;
the if query checked the wrong directory;
the inner for loop has been removed, because it iterated over all source directories again;
the source and destination paths for the copy command have been adapted;
all paths are properly quoted;
I need to compare two folders using Batch commands. Both the folders have subdirectories and files in them. The comparison must check every file. If there is any difference, for instance if we are comparing folder1 and folder2, and file1 is present in folder1 but it is not present in folder2, then it must return true (so that I can do some other operations), else false.
I am actually doing a copy from one folder to another. Once it's done I need to validate if all the files are copied.
Note: I cannot use any third party tools.
#echo off
REM Writing the folder tree to a file for each path
pushd "Folder 1"
for /f "delims=" %%c in ('tree /f') do >>"%~dp0folder1.txt" echo "%%c"
popd
pushd "Folder 2"
for /f "delims=" %%d in ('tree /f') do >>"%~dp0folder2.txt" echo "%%d"
popd
REM removing the first three lines from each of the two files
more +3 "folder1.txt" >"folder1.txt.new"
move /y "folder1.txt.new" "folder1.txt" >nul
more +3 "folder2.txt" >"folder2.txt.new"
move /y "folder2.txt.new" "folder2.txt" >nul
REM comparing files
fc /b folder1.txt folder2.txt>nul && echo same || echo different
REM cleaning up
del folder1.txt
del folder2.txt
Should work as long as the folders are on the same drive. Changes the directory to the first folder and prints the output of the command tree to one file and same for the other folder.
Then compares a /binary file comparison and outputs same if the outputs of the command and with that the folders are the same. If not it outputs different.
Deletes two help-files after.
NOTE: If you already have files with that names, change it!
Feel free to ask if something is unclear :)
Edit: Remove first 3 lines to prevent comparison faliures based on Volume-Number/Drive-Letter. Credit for the way to remove goes to dbenhams answer to another question.