I have to create a couple of thousand directories.
The directories look like this: 10P001 being YEAR/P,S,L,R,F/Numberfrom001to600
the letters are not systematic, so i have to write them for every folder.
my script until now looks like this, but cmd doesnt like the for loop.
#echo off
setlocal enabledelayedexpansion
set /p jahr=Welches Jahr?
set /p anzahl=Wieviele Projekte?
set looop=%anzahl+1000
for /l %%x in (1001, 1, looop) do (
set nummer=%%x
set /p welches=P1 S2 L3 R4 F5 nichtexistent6?
if %welches%==1 mkdir %jahr%P!nummer:~-3!
if %welches%==2 mkdir %jahr%S!nummer:~-3!
if %welches%==3 mkdir %jahr%L!nummer:~-3!
if %welches%==4 mkdir %jahr%R!nummer:~-3!
if %welches%==5 mkdir %jahr%F!nummer:~-3!
if %welches%==6 echo "nicht existent"
)
pause
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /f "tokens=1,2delims= " %%a IN (q28608207.txt) DO (
FOR /l %%x IN (1001,1,1011) DO (
SET seq=%%x
ECHO(MD %%a%%b!seq:~-3!
)
)
GOTO :EOF
I used a file named q28608207.txt containing this data for my testing.
10 P
10 S
The routine reads the two fields from the file as %%a and %%b, then for a loop varying %%x from 1001 by 1 to 1011 (it can of course be 1600 - 1011 just proves the point), copy %%x to a temporary veriable (because substringing can't be applied to the metavariable %%x) create a directory named %%a%%b and the last 3 characters of the temporary variable.
Note that the setlocal enabledelayedexpansion command enables the use of !var! (accessing the value of var as it varies)
The required MD commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MD to MD to actually create the directories. Append 2>nul to suppress error messages (eg. when the directory already exists)
To create a file containing the required numbers:
#echo off
setlocal enabledelayedexpansion
set /p jahr=Welches Jahr?
set /p anzahl=Wieviele Projekte?
set looop=%anzahl+1000
(
for /l %%x in (1001, 1, looop) do (
set nummer=%%x
echo %jahr%P!nummer:~-3!
)
)>J%jahr%.txt
This would produce a list (for jahr=14,say) in J14.txt
14P001
14P002
14P003
and then all you need do is edit the file (use notepad, not a word-processor) to replace the "P" with whatever letter is required. delete any line where no directory is required.
The resultant file could then be processed to directories by using
#ECHO OFF
SETLOCAL
FOR /f %%a IN (J14.txt) DO (
ECHO(MD "%%a"
)
GOTO :EOF
my solution for now (i know its worse than bad habit, but it works and will save me a lot of time (or at least my company some money)):
#echo off
setlocal enabledelayedexpansion
set /p jahr=Welches Jahr?
set /p anzahl=Wieviele Projekte?
set /a looop=%anzahl%+1000
set /a count=1001
:LoopStart
set /p welches=P1 S2 L3 R4 F5 nichtexistent6?
if !welches!==1 mkdir %jahr%P!count:~-3!
if !welches!==2 mkdir %jahr%S!count:~-3!
if !welches!==3 mkdir %jahr%L!count:~-3!
if !welches!==4 mkdir %jahr%R!count:~-3!
if !welches!==5 mkdir %jahr%F!count:~-3!
if !welches!==6 echo "nicht existent"
set /a count=%count%+1
if %count% leq %looop% (goto LoopStart) else (goto:eof)
pause
Related
Im trying to make a batch-file that creates random directories and create files in the folders. But I am unable to make it work.
This is what I have tried:
#echo off
cd "%userprofile%\desktop\Safe_Space"
md "%random%"
md "%random%"
md "%random%"
cd "*"
copy /Y NUL %random%.txt >NUL
This will create 10 folders with random names and 1 file within each folder with random names.
This will create a completely empty file in the created directories:
#echo off
setlocal enabledelayedexpansion
for /l %%i in (1,1,10) do (
set tempf=!random!
mkdir !tempf!
copy /y NUL !tempf!\!random! >NUL
)
Increasing/Decreasing the 10 in for /l %%i in (1,1,10) do ( will increased the number of folders and files. To add more files to folders, repeat echo nul > %random.txt or simply create another loop to create multiple files in the folders.
fsutil is a another option, but requires admin privileges, it will create a nul variable in the file.
#echo off
setlocal enabledelayedexpansion
for /l %%i in (1,1,10) do (
set tempf=!random!
mkdir !tempf!
fsutil file createnew !tempf!\!random! 1
)
This creates a new file, with some text, in this case the word nul will be written to file, but you can change that:
#echo off
setlocal enabledelayedexpansion
for /l %%i in (1,1,10) do (
set tempf=!random!
mkdir !tempf!
echo nul > !tempf!\!random!
)
You can create directories and files by using FOR, RANDOM and basic instructions.
RANDOM create a random number between 0 and 32767. You can control the range of RANDOM using bottomlimit and upperlimit, e.g. 1-1000:
SET /a bottomlimit = 1
SET /a upperlimit = 1000
Don't forget to use SETLOCAL ENABLEDELAYEDEXPANSION (check How do SETLOCAL and ENABLEDELAYEDEXPANSION work?) and inside the loop the !VARIABLE! notation instead of %VARIABLE%. The following example creates 5 directories and 10 empty files. You can change these values as you like, using
FOR /l %%i in (1,1,10) instead of FOR /l %%i in (1,1,2) creates 2 directories.
FOR /l %%i in (1,1,10) means a loop starts at 1, steps by 1, and finishes at 10.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
REM creating 5 directories...
FOR /l %%i in (1,1,5) DO (
SET dirName=!RANDOM!
REM create a directory with random name
MKDIR !dirName!
CD !dirName!
REM creating 10 files...
FOR /l %%i in (1,1,10) DO (
REM create an empty file with random name
COPY NUL !RANDOM!>NUL
)
CD ..
)
The instruction COPY NUL !RANDOM!>NUL doesn't require administation privileges
the >NUL eliminates unwanted output to console
So in Windows Explorer, I have these files sorted like this:
I have this script to remove the brackets and one zero, and in case the trailing number is greater than or equal to 10, to remove two zeroes:
cd C:\folder
setlocal enabledelayedexpansion
SET /A COUNT=0
for %%a in (*.jpg) do (
SET /A COUNT+=1
ECHO !COUNT!
set f=%%a
IF !COUNT! GTR 9 (
set f=!f:^00 (=!
) ELSE (
set f=!f:^0 (=!
)
set f=!f:^)=!
ren "%%a" "!f!"
)
pause
However, once I run the code, I get this result:
So the batch file isn't going through the files "intuitively" like Windows Explorer shows them. Is there any way to change this? Or is there a better way to rename these files altogether?
This uses a different approach:
#echo off
cd C:\folder
setlocal enabledelayedexpansion
SET /A COUNT=0, REMOVE=2
for /F "delims=(" %%a in ('dir /B *.jpg') do (
SET /A COUNT+=1
ECHO !COUNT!
set "f=%%a"
IF !COUNT! EQU 10 SET "REMOVE=3"
for /F %%r in ("!REMOVE!") do set "f=!f:~0,-%%r!"
ren "%%a" "!f!!COUNT!.jpg"
)
pause
Here is a method that does not depend on the sort order used by the file system, preserving the numbers as occurring in the original file names.
For each file name (for instance, test_this_01 SELR_Opening_00000 (1).jpg), the portion after the last under-score _ is retrieved (00000 (1)). Then the parentheses and the space are removed and then the length is trimmed to five characters (00001). This string replaces the original one in the file name finally (test_this_01 SELR_Opening_00001.jpg); the file name must not contain the replaced portion (00000 (1)) multiple times (hence file names like this should not occur: test_this_00000 (1) SELR_Opening_00000 (1).jpg):
#echo off
setlocal DisableDelayedExpansion
rem // Define constants here:
set "LOCATION=."
set "PATTERN=*_* (*).jpg"
set /A "DIGITS=5"
pushd "%LOCATION%" || exit /B 1
for /F "usebackq eol=| delims=" %%F in (`
dir /B /A:-D /O:D /T:C "%PATTERN%"
`) do (
set "FILE=%%F"
setlocal EnableDelayedExpansion
set "LAST="
for %%I in ("!FILE:_=","!") do (
set "LAST=%%~nI" & set "FEXT=%%~xI"
set "FNEW=!FILE:%%~I=!"
)
set "LAST=!LAST:(=!" & set "LAST=!LAST:)=!"
set "LAST=!LAST: =!" & set "LAST=!LAST:~-5!"
ECHO ren "!FILE!" "!FNEW!!LAST!!FEXT!"
endlocal
)
popd
endlocal
exit /B
Adapt the directory location and the file search pattern in the top section of the script as you like.
After having tested, remove the upper-case ECHO command in order to actually rename files.
I'm having a bit of trouble with a FOR DO command in a .BAT file I'm working on for work.
Here is the entire code I'm working with
SET parent="%~dp0"
SET GroomedDir="%~dp0Groomed\"
XCOPY /s/e/y Groomed %parent%NewGroomed\
CD NewGroomed
setlocal enabledelayedexpansion
FOR %%i in (IMG_*.jpg) DO (
SET OldName=%%i
SET ImgNumber=!OldName:~4,-4!
SET DBLookup=FINDSTR !ImgNumber! Database.txt
!DBLookup! > return.txt
FOR /F "tokens=1-5 delims=|" %%J in (return.txt) do (
REN !OldName! "%%K_%%L.jpg"
MKDIR %%M\%%N
MOVE "%%K_%%L.jpg" %%M\%%N
)
)
del return.txt
endlocal
cd ..
ren Groomed "Groomed Backup"
ren NewGroomed Groomed
The trouble come in lines 12-14 (I put in line separators). I can't seem to put the variable %DBLookup% into the FOR command, and am forced to use a placeholder text file instead. It works, in the end, but wouldn't it be better to save myself the write to return.txt operation, and the read return.txt operation?
For context, return.txt contains a single line from of text like this:
115525|Last_First|5233|8|Teacher
I use the FOR command because it allows me to delimit using the pipe character, or whatever else, and output to %%J %%K %%L %%M and %%N variables.
Any help or advice for this relative newcomer is much appreciated!
Here's my code with my comments:
REM THESE FOUR LINES:
REM 1) SET A VARIABLE FOR THE PARENT DIRECTORY LOCATION,
REM 2) SET A VARIABLE FOR THE GROOMED DIRECTORY,
REM 3) COPY THE GROOMED DIRECTORY TO "NEWGROOMED\",
REM 4) CHANGE THE LOCATION TO BE WORKING ENTIRELY WITHING NEWGROOMED\
SET parent="%~dp0"
SET GroomedDir="%~dp0Groomed\"
XCOPY /s/e/y Groomed %parent%NewGroomed\
CD NewGroomed
REM THIS FOR LOOP LOADS ALL JPGS IN THE \NEWGROOMED\ DIRECTORY THAT BEGIN WITH THE STRING, "IMG_"
setlocal enabledelayedexpansion
FOR %%i in (IMG_*.jpg) DO (
SET OldName=%%i
REM THIS LINE COPIES THE OLD NAME MINUS THE FIRST FOUR CHARACTERS, "IMG_", AND MINUS THE EXTENSION (LAST 4 CHARS)
SET ImgNumber=!OldName:~4,-4!
REM THESE NEXT TWO LINES LOOK UP OUR IMAGE NUMBER IN DATABASE.TXT AND RETURN THE ENTIRE LINE TO A NEW FILE CALLED RETURN.TXT
SET DBLookup=FINDSTR !ImgNumber! Database.txt
!DBLookup! > return.txt
REM NOW WE PARSE RETURN.TXT USING PIPE DELIMITERS INTO THE VARIABLES J,K,L,M,N (ID,Name,IMG#,Grade,Homeroom)
FOR /F "tokens=1-5 delims=|" %%J in (return.txt) do (
REN !OldName! "%%K_%%L.jpg"
MKDIR %%M\%%N
MOVE "%%K_%%L.jpg" %%M\%%N
)
)
del return.txt
endlocal
cd ..
ren Groomed "Groomed Backup"
ren NewGroomed Groomed
Overall, my goal is to begin with a folder, "Groomed," with a bunch of images titled as such: IMG_####.jpg.
My batch file will:
1) create a backup of the entire starting directory
2) rename each image according to the database.txt file
3) move each renamed image into a new grade/teachername folder
I am starting with a file, (database.txt) that comes to me from another employee. The file is a plain list for each student in the following format: student id|lastname_firstname|image#|grade#|teachername.
As i mentioned. The file works perfectly, but since I'm new to batch files I was feeling like it might be dumb of me to write to a throwaway file just to save a string and then delete it. That's what variables are for, but I was having a hard time getting that variable to pass into the FOR command.
sample of Database.txt
659968|Saperstein_Ryan|4603|7|Hallock
015520|Qian_Emily|2528|7|Hallock
528852|Rizzo_Jason|4618|7|Krukowski
and a few filenames I'm starting with:
IMG_2528.jpg
IMG_4544.jpg
IMG_7044.jpg
IMG_6880.jpg
IMG_4839.jpg
Edit:
A first bunch by parsing database.txt first and then compare by using if exist. The second is by comparing variables
code:
rem create a sample of the following example
rem :: student id|lastname_firstname|image#|grade#|teachername
rem :: The common points are only in the first 3 jpg
copy nul IMG_4603.jpg
copy nul IMG_2528.jpg
copy nul IMG_4618.jpg
copy nul IMG_4619.jpg
copy nul IMG_4620.jpg
copy nul IMG_4630.jpg
(
echo 659968^|Saperstein_Ryan^|4603^|7^|Hallock
echo 015520^|Qian_Emily^|2528^|7^|Hallock
echo 528852^|Rizzo_Jason^|4618^|7^|Krukowski
echo 528817^|Rizzo_Jas17^|4617^|7^|Krukows17
echo 528816^|Rizzo_Jas16^|4616^|7^|Krukows16
)>sample.txt
rem :: type sample.txt
rem :: pause
Method #1
#echo off
setlocal enabledelayedexpansion
for /f "tokens=1-5 delims=|" %%a in (sample.txt) do (
set "student_id=%%a"
set "student_name=%%b"
set "student_image=%%c"
set "student_grade=%%d"
set "student_teacher=%%e"
rem :: echo !student_name!_!student_image!.jpg
if exist "IMG_!student_image!.jpg" (
rem :: remove echo in the following lines if it's okay.
echo:
echo ren "IMG_!student_image!.jpg" "!student_name!_!student_image!.jpg"
echo mkdir "!student_grade!\!student_teacher!"
echo move "!student_name!_!student_image!.jpg" "!student_grade!\!student_teacher!"
)
)
Method #2
#echo off
setlocal enabledelayedexpansion
for %%i in (IMG_*.jpg) do (
set "OldName=%%~i"
set "image_number=!OldName:~4,-4!"
rem :: echo image_number: !image_number!
for /f "tokens=1-5 delims=|" %%b in (
'findstr !image_number! sample.txt'
) do (
set "student_id=%%a"
set "student_name=%%b"
set "student_image=%%c"
set "student_grade=%%d"
set "student_teacher=%%e"
if "!student_image!"=="!student_image!" (
rem :: remove echo in the following lines if it's okay.
echo:
rem :: echo !image_number! = !student_image!
echo ren "IMG_!student_image!.jpg" "!student_name!_!student_image!.jpg"
echo mkdir "!student_grade!\!student_teacher!"
echo move "!student_name!_!student_image!.jpg" "!student_grade!\!student_teacher!"
)
)
)
output:
ren "IMG_2528.jpg" "Qian_Emily_2528.jpg"
mkdir "7\Hallock"
move "Qian_Emily_2528.jpg" "7\Hallock"
ren "IMG_4603.jpg" "Saperstein_Ryan_4603.jpg"
mkdir "7\Hallock"
move "Saperstein_Ryan_4603.jpg" "7\Hallock"
ren "IMG_4618.jpg" "Rizzo_Jason_4618.jpg"
mkdir "7\Krukowski"
move "Rizzo_Jason_4618.jpg" "7\Krukowski"
I have a million old text files that I need to convert the format on. I have been desperately trying to do this myself but I really could use help. I am trying to convert data that looks like this:
text
11111.111
22222.222
33333.333
text2
44444.444
55555.555
66666.666
77777.777
88888.888
99999.999
(each number is on a seperate line and there are some blank lines, but I need them to go into the output file as a place keeper)
Into a .txt file that looks like this:
**I also need to add an increment number at the beginning of each line to number the lines.
1,11111.111,22222.222,33333.333,text
2,44444.444,55555.555,66666.666,text2
3,77777.777,88888.888,99999.999,
the files that I have are in separate folders in a directory and have no file extension but they behave exactly like a standard text file.
I have tried all sorts of stuff but I am just not that well versed in programming. Here is the little bit of code that I havent deleted for the 100th time. gettting frustrated
:REFORMAT
FOR %%F IN (*) DO IF NOT %%~XF==.BAT (
SETLOCAL DISABLEDELAYEDEXPANSION
(
SET /P LINE1=
SET /P LINE2=
SET /P LINE3=
SET /P LINE4=
)<"%%F"
ECHO %LINE2%,%LINE3%,%LINE4%,%LINE1%>>"%%F".TXT
PAUSE >NUL
:END
I am using windows I have access to dos6 dos7 winxp 32 and win7 64
the text and text2 are text strings within the file, they are descriptors telling me what the numbers below mean and some of the descriptors are left out. I also need it to process more than the first four lines. Some files have up to 200 lines inside of them. Thank you so much for helping me. thank you so much dbenham here is the final result:
#echo off
setlocal enableDelayedExpansion
for /R %%F in (*.) do (
set /a ln=0
for /f %%N in ('type "%%F"^|find /c /v ""') do set /a cnt=%%N/4
for /l %%N in (1 1 !cnt!) do (
for %%A in (1 2 3 4) do (
set "ln%%A="
set /p "ln%%A="
)
set /a ln+=1
echo !ln!,!ln2!,!ln3!,!ln4!,!ln1!
)
) <"%%F" >"%%F.CSV"
Using nothing but pure native batch:
#echo off
setlocal enableDelayedExpansion
for %%F in (*.) do (
set /a ln=0
for /f %%N in ('type "%%F"^|find /c /v ""') do set /a cnt=%%N/4
for /l %%N in (1 1 !cnt!) do (
for %%A in (1 2 3 4) do (
set "ln%%A="
set /p "ln%%A="
)
set /a ln+=1
echo !ln!,!ln2!,!ln3!,!ln4!,!ln1!
)
) <"%%F" >"%%F.txt"
The above will process all files that have no extension in the current folder. If you want to recursively include all sub-folders, then add the /R option to the outer FOR statement.
The whole thing can be done quite simply using my REPL.BAT utility:
#echo off
for %%F in (*.) do (
<"%%F" repl "([^\r\n]*)\r?\n([^\r\n]*)\r?\n([^\r\n]*)\r?\n([^\r\n]*)\r?\n?" "$2,$3,$4,$1\r\n" mx|findstr /n "^"|repl "^(.*):" "$1," >"%%F.txt"
)
just a few modifications:
set /p doesnt delete a variable if input is empty, so you have to delete it before.
You missed a closing paranthese )
You have to use delayed expansion to use a changed variable inside parantheses
the counter.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set count=0
FOR %%F IN (*.) DO IF NOT %%~XF==.BAT (
set "LINE1="
set "LINE2="
set "LINE3="
set "LINE4="
set count+=1
(
SET /P LINE1=
SET /P LINE2=
SET /P LINE3=
SET /P LINE4=
)<"%%F"
ECHO !count!,!LINE2!,!LINE3!,!LINE4!,!LINE1!>>"%%F.txt"
)
PAUSE >NUL
:END
How do I write a windows batch file that stores all of the folder names in a directory in individual variables? I do not know how many folders will be in the directory at any given time. I'm pretty sure that I need a for loop.
Here is what I've tried so far:
#ECHO OFF
set /a c=1
setlocal ENABLEDELAYEDEXPANSION
for /d %%f in (c:\users\*) do echo.file %%f
for /d %%A in (c:\users\*) do (set "var!c!=%%A")
ECHO.%var!c!%
perhaps What you can do is write the output of command
dir /AD
in some file called as folders.txt then can do operations on number of folders by storing them into any an array variable , something like this.
for %%G in (folders.txt) do (
set /a count+=1
call :exec1 %%~nG
echo %%~nG
)
goto :continue1
:exec1
echo %count%
set mapArray[%count%]=%1
goto :end
:continue1
:end