Batch Sorting System - sorting

So my batch file is supposed to do this:
I have a few hundred WinRAR generated "(NAME).part???.rar" files that i want to put into a generated folder tree.
It should put the first 10 files (from 001 to 010) into a new folder named 001 (not just 1).
Then it takes the next ten (011-020) and put them into 002.
I i have fixed everything with adding the zeros automaticly, and i tested all variables but i can't get the actual file movement to work.
Here is what i'm trying to execute:
move "%FILENAME%" %LOOP2%\
%LOOP2% and is just the var %LOOP% (which starts at 1 and goes +1 every tenth loop) with all needed zeros in front of it (so 007, 035 and 455 etc.).
%FILENAME% comes from some more variables:
set FILENAME=%NAME%.part%COUNT2%.rar
%NAME% holds the name of the file/files/filepack (?) i want to move,
e.g. "Splitted file.part001.rar" would be "Splitted file"
(entered by user)
%COUNT2% starts at 1 and increases every loop until it matches the user-entered %NUMBER% var, which is the last file number (e.g. 468). It comes from %COUNT% which i don't want to change, so i created %COUNT2%.
I tried almost everything but sometimes cmd tells me the file or directory wasn't found or it suddenly closes displaying something with "can't syntacticly be used here" for a brief moment.
(Also the message is translated from German!)
People talk lot about putting double percent signs or double quotes or no quotes and so on and i tried most combinations but still i can't get it to work.
Can someone give me the right syntax and tell me where and how i have to use quotes and double percent signs?
I know my code and this text is pretty messy but i'm still learning :)
Ofc i asked Dr. Google and Stackoverflow but i think my case is a bit specific.

You have not shown your code and there is no way to guess what the problem is, so I created my own:
#echo off
setlocal EnableDelayedExpansion
set /P "NAME=Enter name of file/files/filepack (NO quotes): "
set /P "NUMBER=Enter number of files to copy: "
set /A COUNT2=1000, LOOP2=1000
for /L %%i in (1,1,%NUMBER%) do (
set /A COUNT2+=1, COUNT2mod10=COUNT2 %% 10
if !COUNT2mod10! equ 1 (
set /A LOOP2+=1
md !LOOP2:~1!
)
move "%NAME%.part!COUNT2:~1!.rar" !LOOP2:~1!
)

Related

How to remove leading whitespace from first line of text files using batch file in Windows?

I've got about 700 .tcx files (old GPS running data if you're interested...).
The first line is:
<?xml version="1.0" encoding="UTF-8"?>
That's 10 spaces at the start, which is preventing me from importing this data to Garmin Connect (I got a new Garmin watch).
So, I need to remove this whitespace from the front of this first line of 700 files. I'm trying to automate this process with a batch file (though given how long I've spent trying to do this, it would've been quicker to do it by hand...)
So far I've got:
#echo off
setlocal enabledelayedexpansion
for /F "tokens=1" %%A in (C:\[path]\[filename].tcx) do (
set line=%%A
echo !line:~1! >> C:\[path]\[filename].tcx
)
endlocal
Where [path] is the path to where the files are currently stored, and filename is the file I'm testing on. Once I've got it working I will replace [filename[ with *
Unfortunately what I've got isn't quite working at the moment:
Firstly, it is going through the whole file, not just the first line.
Secondly, on each line, it is not just deleting the leading whitespace, it is deleting everything upto and including the first character (which is a "<") and then also deleting everything after the next space that is comes across.
I know my attempt is kind of pathetic, but I'm hoping to learn!
#ECHO OFF
SETLOCAL
rem The following settings for the directories are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
FOR %%e IN ("%sourcedir%\*.tcx") DO (
SET "first=y"
(
FOR /f "usebackqtokens=*" %%y IN ("%%e") DO IF DEFINED first SET "first="&ECHO %%y
FOR /f "usebackqskip=1delims=" %%y IN ("%%e") DO ECHO %%y
)>"%destdir%\%%~nxe"
)
GOTO :EOF
Always verify against a test directory before applying to real data.
Note that if the filename does not contain separators like spaces, then both usebackq and the quotes around %filename1% can be omitted.
This should accomplish the task. It simply reads the first line from each file, removing leading spaces (one of the default delims) and sends it to the output, resetting the first flag to prevent regurgitation of the remaining data.
Next step is to reproduce all but the first line.
All gathered together by enclosing the two fors in parentheses and redirecting.
Note that the source and destination directories must be different.

Batch combine new elements into subtitle files

I want to take a folder with several (15 in this first case) 'subtitle.srt' files (which, as I'm sure you're aware, are just text files with the extension ".srt" instead of ".txt") and modify each file in turn so that a new subtitle is added at the start of each file.
I want the new subtitle to be:-
0
00:00:00,001 --> 00:00:02,100
"Filename"
So, for example, if the first subtitle file in the folder is called "01. What Lies Beneath.srt" and it looks like this:-
1
00:00:02,120 --> 00:00:03,560
<font color="#FFFF00">Previously on Superman & Lois...</font>
2
00:00:03,560 --> 00:00:06,880
<font color="#00FFFF">I'm stepping down from active duty.</font>
<font color="#00FF00">You're going to be hard to replace.</font>
3
Etc., etc...
then after processing, I want it to look like this:-
0
00:00:00,001 --> 00:00:02,100
01. What Lies Beneath
1
00:00:02,120 --> 00:00:03,560
<font color="#FFFF00">Previously on Superman & Lois...</font>
2
00:00:03,560 --> 00:00:06,880
<font color="#00FFFF">I'm stepping down from active duty.</font>
<font color="#00FF00">You're going to be hard to replace.</font>
3
Etc., etc...
I'm rubbish at batch coding so I tried searching out possible ways to do it but nothing I tried worked!
Below are some attempts I made using different "routines" I found; each successive attempt separated (from last to first) by the PAUSE, EXIT commands:-
for %%a in (*.txt) do type append_ns0 >> %%a.srt
pause
exit
for %%a in (*.txt) do type append_ns0 >> %%a
for %%a in (*.txt) do type "%%~na" >> %%a
for %%a in (*.txt) do type append_spc >> %%a.srt
pause
exit
for %%I in (*.txt) do copy "C:\Users\wbcam\Desktop\G classroom\AddTitle.txt"+"%%~nI"+" "+"%%I" "%%~nI.srt"
pause
exit
for %X in (C:\Users\wbcam\Desktop\G classroom\Add Titles\*.txt) do type C:\Users\wbcam\Desktop\G classroom\AddTitles.txt >> %X
pause
exit
To use the COPY command I had to first rename the files from .srt to .txt (I'd rather NOT have to do that; I'm hoping someone can show me how to work on the ,srt files without any intermediate stages) and COPY also seemed to add a hex1A character to the end of the new file but, of course, it couldn't handle the insertion of the Filename (a text string) into the new file as it would only concatenate files not strings (if I, eventually, understood it's operation correctly, Doh!).
And attempts to use the ECHO or TYPE commands just seemed to overwrite everything in the original file leaving only:-
0
00:00:00,001 --> 00:00:02,100
and bugger all else!
Can anyone help out, please?
#ECHO OFF
SETLOCAL
rem The following setting for the source directoryis a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
FOR /f "delims=" %%b IN (
'dir /b /a-d "%sourcedir%\*.srt" '
) DO (
(
ECHO 0
ECHO 00:00:00,001 --^> 00:00:02,100
ECHO "%%~nb"
ECHO.
TYPE "%sourcedir%\%%b"
)>"%sourcedir%\%%~nb.txt"
MOVE "%sourcedir%\%%~nb.txt" "%sourcedir%\%%b" >NUL
)
GOTO :EOF
Always verify against a test directory before applying to real data.
Perform a directory scan. assigning each filename that matches the mask to %%b.
Write the two required lines, a line containing the name part of the filename in quotes and an empty line to the output, then type the contents of the selected file. Note that the > character in the text needs to be escaped by a caret. The output of the echoes is gathered and redirected to a .txt file and the .txt file is then written over the original file. The 1 file(s) copied message is suppressed by the >nul.
If you prefer, you could replace the two echo lines that insert the fixed text with type somefilename where somefilename contains the fixed text required.
You could replace the move line for testing with
FC "%sourcedir%\%%~nb.txt" "%sourcedir%\%%b"
which will show the differences.
copy adds the control-z following an archaic convention that ^Z marked end-of-file for text files.
--- Addition in response to comment
for /? from the prompt generates documentation about the for command - in general, commandname /? generates documentation for any command, although some commands require -? or -h or --h or --help. Utility designers generally follow the same convention and the details depend on the platform for which the software was originally designed.
for /f ... ('command....') do ... interprets the command-output as though it was a file.
The dir command reports the filenames and subdirectorynames in a directory. By default, it produces a formatted report including filesize and last-update date, but has numerous options including /b to produces a "basic" report (names only, no sizes, headers, summary, dates ,etc.) and /a-d which suppresses directorynames. The /s option means 'and list subdirectories too'. It can also accept a filemask (or ambiguous filename) - which applies equally to directorynames. If the filename supplied contains a ? then this means any ONE character or * which means any number of any characters - any other characters are taken literally and will match regardless of case. Hence, *.srt means any number of any characters followed by .srtwhich should select all file/directorynames that end.srt. The filemask may be preceded by *directoryname\\* which means scan this directory- but *that* directoryname may **not** contain?or*`.
When for /f is supplied with a filename list in basic form, each filename in the list is assigned to the metavariable assigned (%%a in this example) in turn and the do statements are executed using the assigned value in the metavariable. Again, there are many ways of having for /f interpret the value-string that is assigned to the metavariable. Many, many examples of these on SO
In the days of CP/M, filesize was a number of 128-byte blocks. Since files were not often a multiple of 128 bytes long, convention was that a control-z marked the end-of-file. Backwards-compatibility is a big issue in computing as it's wasteful to revise existing systems to cater for a concept-revision. Hence, the control-Z convention is still recognised and observed for text files.

Gather files of a similar filename programmatically

I have a photobooth that will dump all the pictures as they're taken onto a helper PC on the same network.
On the helper PC, I had planned to have a scheduled task run every x minutes to perform some edits on the images using ImageMagick (eg montage, label, etc).
The files are named via timestamp and it takes 4 at a time, so if a few people back to back used the photobooth, then it would transfer the following files to the helper PC:
2016-01-29-22-05-01.jpg
2016-01-29-22-05-02.jpg
2016-01-29-22-05-03.jpg
2016-01-29-22-05-04.jpg
2016-01-29-22-07-01.jpg (note the timestamp change)
2016-01-29-22-07-02.jpg
2016-01-29-22-07-03.jpg
2016-01-29-22-07-04.jpg
I was initially using a batch file to just serve *.jpg into ImageMagick, but now I realise if two people use the photobooth in < x minutes, then there will be two sets of images (like the above). Handing 8 pictures instead of 4 to ImageMagick will result in a mess.
My question is - how can I identify files which a similarly named (eg, first 16 characters are the same) and just pass these to ImageMagick?
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\transferred.log"
IF NOT EXIST "%filename1%" ECHO xxx>>"%filename1%"
:again
SET "transfer="
FOR /f "tokens=1-6delims=-" %%a IN (
'dir /b /a-d /on "%sourcedir%\*.jpg"^|findstr /b /v /g:"%filename1%"'
) DO (
SET "transfer=%%a-%%b-%%c-%%d-%%e"
GOTO movefiles
)
ECHO no new files to MOVE
GOTO :EOF
:movefiles
>>"%filename1%" ECHO %transfer%
:: don't know what you want from here
ECHO transfer %transfer%* ??
SET "transfer=%transfer%-01.jpg %transfer%-02.jpg %transfer%-03.jpg %transfer%-04.jpg"
ECHO transfer %transfer% ??
:: perhaps a delay here for helper PC to process??
timeout /t 5 >nul
GOTO again
You would need to change the settings of sourcedir and filename1 to suit your circumstances.
You haven't told us what happens to the files you want grouped, so I've assumed they remain.
The meat of the matter is the for - grab the first 6 tokens using - as separators and apply to a directory-list in basic form without directories sorted in name order and filtered for lines that begin with a string which does not appear in filename1
If any such line is found, gather the name into transfer, and do something with that value (not specified), recording the value in the log so that the next loop includes the value found in its exclude-list.
I don't have time to code this, but you could do the following
Get current date and time to the second
Format it like the filenames (set mydatetime=2016-01-29-22-07)
for /r %i in (%mydatetime%*) do move %i %targetpath%
wait 1 minute PING 127.0.0.1 -n 1 -w 60000 >NUL
loop
(this assumes only one batch per minute as you indicated in the comments above)
However, if you have the ability to modify the output (as indicated by adding "a couple of 1 second sleeps") I wonder like everyone else why you don't just make the output more robust? Separate folders, batch names, etc.

How can I pad numbers with leading zeros, to a fixed length?

I've tried so sort this for the better part of the morning.
It is actually the same question as this one from 2013, to which no one replied:
batch script with FOR does not work
I'll do my best to format the code so that it is easy to follow and maybe I'll get an answer...
I am doing an archive project from our help desk ticket system.
For sorting purposes, the files will have the ticket number and the date.
However, the ticket number varies in length. To fix this, all ticket numbers are to be 6 digits, with the shorter numbers padded with preceding zeroes (i.e. 1234 becomes 001234).
I can get the ticket number, but I need to find its length to know how many zeroes to add.
This works:
echo off
set my_str=12345
set length=0
:Loop
if defined my_str (
set my_str=%my_str:~1%
set /A "length+=1"
goto Loop)
echo the string is %length% characters long
However, I get a bunch of ticket numbers in a list.
So, I read through this:
set statements don't appear to work in my batch file
And got lost reading this:
http://www.computing.net/howtos/show/batch-script-variable-expansion-win200-and-up/248.html
And I tried this:
setlocal enabledelayedexpansion
echo off
for /f %%a IN (test.txt) do (
set my_str=%%a
set length=0
:Loop
if defined my_str (
set my_str=!my_str:~1!
set /A "length+=1"
echo %length%
goto Loop)
echo the string is %length% characters long
)
But it only reads the FIRST line of test.txt
Why does the FOR /F loop fail?
How do I get it to work?
You do not need to know the length of the ticket number string (when you can assure it won't be longer than 6 characters), you can prefix 5 zeros and split off the last 6 characters then:
set my_str=12345
set my_str=00000%my_str%
set my_str=%my_str:~-6%
echo %my_str%
If you still want to get the string length, consult this post.
You cannot use goto within the for body as goto breaks the for loop context. However, you can call a sub-routine within for, which in turn may contain goto.
Your batch script does exactly what you are describing: reading the first line of a number of files (in your case, only the one file) and determining the length of the first line. I.e. you got the inner part of your for loop wrong.
I don't know the correct solution either but I think that this page may be of some help to you:
http://ss64.com/nt/for_f.html
I hope that helps.
This seems like a XY problem. Instead of worrying about calculating the length of a string, just use the built-in substring methods to create a padded string.
#echo off
setlocal enabledelayedexpansion
for /f %%a IN (test.txt) do (
set my_str=000000%%a
#echo !my_str:~-6!
)
The end result echo'ed will be a six-digit number left-padded with zeroes.

remove first characters of multiple file names with a bat file - what is ~%X%,?

I need to create a script, that will remove first six characters from a huge amount of files (with different names). I tried this example from another question, but I want to understand it better:
#echo off
setlocal enabledelayedexpansion
set X=3
for %%f in (*) do if %%f neq %~nx0 (
set "filename=%%~nf"
set "filename=!filename:~%X%,-%X%!"
ren "%%f" "!filename!%%~xf"
)
popd
I can see, that modifying the X in -%X%! I actually trim the X number of first characters from all the files in the folder. I don't know what the ~%X%, is - I can only see that if it is not a number higher than 0, the script won't run. I also don't know what set X=3 is - I can only see that there is no difference whether it is present in the bat file or not. Could anyone please explain to me the syntax of this file?
Thanks in advance!
That method is called Substring.
You can see a lot of examples and explanation here: http://ss64.com/nt/syntax-substring.html
The first number is the start index, and the second number is the last index of.
Example:
#echo off
Set "Filename=TestFile.txt"
Set "Filename=%Filename:~0,-4%"
Echo %FILENAME%
pause
In that code we start reading from index "0" (the first letter of the string), and stop reading at "-4", then we substract from 0 to -4 so the result is: "TestFile"
I hope this helps.

Resources