i would like to ask about MS-DOS batch file to determine that file name in character or digits or is there a way to specify how to dir, copy or xcopy all files which it's names has numerical only.
You may find a tool appropriate in Georg Pohl's collection of DOS utilities, or in the Batfiles downloads.
If you do want to make a pure-batch solution, the following links from the Batfiles FAQ will get you started:
Place first character of string into a variable, Remove 1st character of string and place remainder into variable.
there is a way to check that ...little bit messy but here you go.
for %%i in (.) do (
echo %%~nfile1|findstr /r "[0-9]"
if /i %errorlevel% neq 0 set result=letters
if /i %errorlevel% == 0 set result=numbers )
this should go through all files,
hide extensions, and check if all characters are numbers
if not all numbers, it will set variable %result% as letters.
hope this helps
Related
I have a file as "RAAAAAAV.KKK9.Z01_YYYYMMDDhhmmss". I want to remove the last part after the underscore"_" using a one liner dos command. Please help.
Output required:
RAAAAAAV.KKK9.Z01
The following works
#echo off
set var=RAAAAAAV.KKK9.Z01_YYYYMMDDhhmmss
set "var=%var:_="&rem %
set var
To rename a specific file:
ren "RAAAAAAV.KKK9.Z01_20151009231015" *.Z01
To rename all files with extension like Z01_timestamp:
ren *.Z01_?????????????? *.Z01
To rename all files where the beginning of the extension is unknown:
for %F in (*.???_??????????????) do #for /f "delims=_" %X in ("%~xF") do #ren "%F" "%~nF%X"
If used in a batch script, then percents must be doubled:
#echo off
for %%F in (*.???_??????????????) do for /f "delims=_" %%X in ("%%~xF") do ren "%%F" "%%~nF%%X"
EDIT - 2015-10-10
If you really want to have precise control over which files get renamed, then you can use my JREN.BAT regular expression renaming utility - a hybrid JScript/batch script that runs natively on any Windows machine from XP onward. The following simple one liner strips off the underscore and timestamp from any file that has an extension consisting of any combination of letters and digits, followed by an underscore, followed by a 14 digit timestamp.
jren "(\.[A-Z0-9]+)_\d{14}$" $1 /i
Maybe already late, but I will share my founding anyway for benefit to others.
You can use batch sub-procedure/function
:leftStr STRING SEPARATOR RESULT_VAR
::get left string before some specific SEPARATOR
set "STRING=%~1" get arg1
set "RIGHT=%STRING:*%~2=%" anything after arg2
set "%~3=!STRING:%~2%RIGHT%=!" strip that substr
exit /b
Then you can call it from other places, works even inside for loop with delayedExpansion enabled.
..
call :leftStr "left_right" "_" varname
echo !varname!
#rem varname = left
note: this is not a fancy function, no error checking or such. You'd better make sure your input string, separator, return_var is already valid or no conflict with any other.
EDIT: forgot to mention, this is for arbitrary length string and separator, for a simple, fixed length you can just use %var:~-N1,N2% (with negative N1)
I have a list of files that I'm looping through that match a certain size letter (A,B,C,D). The files are of the form ###T#####A###_# rev 1.dxf, where the rev 1 is only there some of the time, and A refers to the size, which is A, B, C, or D. When I try to loop through these in a set D.dxf or B.dxf, some A files are also found. I currently use the pattern ?????????A*.dxf, but would like to expand this to more file types without having to make multiple batch files. Interestingly, if I use the pattern TA*.dxf, the wildcard behaves normally.
Why does this happen, and how can I fix it while still being to catch files where the A may be at the beginning, end, middle, etc? If you need any clarification or extra information, feel free to ask.
Here is my relevant code:
FOR %%S IN (A,B,C,D) DO (
echo Converting size %%S. . .
FOR %%F in ("%filepath%\?????????%%S*.dxf") DO (
echo Converting %%~nxF to PDF, size %%S
SET %%S=!%%S! "%%~pF%%~nF.pdf"
"C:\Program Files\AutoDWG\AutoDWG DWG to PDF Converter\d2p.exe" /InFile %%~fF /OutFile %%~nF.pdf /Watermark %~dp0%%Swatermark.wdf /InConfigFile %~dp0%%S.ddp
)
echo:
echo Combining %%Ss. . .
pdftk !%%S! cat output "%filepath%\print\%%Ss.pdf"
echo Combined
echo:
)
EDIT: I'm running this on 32-bit Windows XP. Does this have anything to do with this thread? I will investigate when I get home.
EDIT 2: I've now figured out what the problem is. When I have several files with the same beginning characters, the 8.3 short names contain a hexadecimal number, which may match one of the letters I'm searching for. How can I discard short name matches in my for loop?
Your link to the Strange Windows DIR command behavior thread seems to be a good thought. From RBerteig's thorough answer: Wild cards at the command prompt are matched against both the long file name and the short "8.3" name if one is present.... Try next approach:
SETLOCAL enableextensions enabledelayedexpansion
:::
pushd %filepath%
FOR %%F in ("*.dxf") DO (
set "fname=%%~nF"
set "fmatch="
set "char04=!fname:~3,1!"
set "char10=!fname:~9,1!"
if /I "!char04!"=="T" (
FOR %%S in (A B C D) do if /I "!char10!"=="%%S" set "fmatch=!fname!"
)
if defined fmatch (
echo Converting %%~nxF to PDF, size !char10!
rem another stuff here
)
)
popd
I am attempting to create a script that will search through a directory for files whose extension are larger than a specific numerical value. The process I am monitoring creates files with numeric extensions when it runs. My end goal is to delete all files of a certain file name one the extension exceeds 800.
The process runs and creates a file as a result, mainly a log files. When it creates its 800th file the file name would be like "filename.800". The file name can vary but the extension will be anything from 000 - 999. I need to delete "filename.*" for the collection of files that reaches 800 (or other). There are other files of different names but have numeric extensions as well in the same directory. I'm trying to make this part of an automated cleanup process.
I could use some suggestions on how to get started detecting the files exist. My initial attempt below does not seem to heed the 'GTR', 'LSS' options.
forfiles /M *.* /C "%comspec% /c IF #EXT GTR 800 (ECHO #PATH)"
I don't mind entertaining other methods to address my task. Thanks in advance.
The #ext value includes enclosing quotes, so you need to include them in your IF comparison. But adding quotes will throw off the command line parser since the entire command is already enclosed in quotes. Use 0x22 to represent each internal quote.
forfiles /M * /C "cmd /c if #ext gtr 0x228000x22 echo #path"
However, FORFILES is very slow. It is much faster to use a simple FOR loop. The ~x modifier expands to the file extension (including the dot).
The following works on the command line.
for %f in (*) do #if %~xf gtr .800 echo %f
Double the percents if you want to use the command in a batch script.
If you want to delete the files precisely in the 800-999 range, then the easiest and fastest way is this:
for %%a in (8 9) do del filename.%%a??
Previous method could even be adjusted for other different ranges.
#ECHO OFF
SETLOCAL
::method1
FOR %%f IN (*.8* *.9*) DO IF %%~xf gtr .800 IF %%~xf leq .999 ECHO %%f
:: method2
ECHO ======= method 2 ============
FOR %%f IN (*.8* *.9*) DO (
ECHO %%~xf|FINDSTR /r ".[89][0-9][0-9]$" >NUL
IF NOT ERRORLEVEL 1 ECHO %%f
)
The first method may suit, but it also detects filenames such as xxx.8004 xxx.8a9.
The second method is slower, but I believe will reliably detect only filenames that end ".[8 or 9][2 digits]"
The filenames are only ECHOed to the console. Replace the ECHO with DEL to delete the files - after rigorous testing...
So I have a collection of art from the internet; it is very large and spans an extreme amount of subdirectories under the main folder I keep it all under (entitled Uda). I've built up this collection over a period of about 4 years. In the most recent 2 years, I've been organising things I save by artist (most of this comes from the site DeviantArt if it matters). But I have 2 years' worth of files unsorted, all over the place and I'd like to sort them.
I figure this is an ideal time to practice some batch scripting, but... I've not the faintest idea where to start. Google hasn't been very helpful, it's too hard to explain what I want to do in one question, let alone find someone who has needed the same thing and been guided through it. Also, I'd honestly much prefer to pull apart and figure out an already-made script to understand it and learn from it (that's how I tend to learn best).
So can anyone help me? If you don't understand what I want to do:
I wish to make a script where I can input something (i.e. an artist's name) and have a folder made for it under a certain directory (no matter where the batch is being run from or the files drawn from) with the name of the term that was entered, and then all files under another directory with that term found and moved.
For the record, even if I weren't interested in batch scripting, I couldn't use Windows Explorer to search for them all then cut them because I disabled it (for personal reasons).
#ECHO OFF
SETLOCAL
:: Note that SPACES are significant in simple SET statements
:: Set relative or local root (start-point of subtree to scan)
:: Use normal then safemethod 1 then safemethod2 - all do the same thing
:: Note : from the prompt,
:: command /?
:: will generally show help...
SET relroot=c:\wherever
(SET relroot=c:\wherever)
SET "relroot=c:\wherever"
:: repeat for destination directory
SET "destdir=c:\destination"
::
:: Read Artist
:: Make sure ARTISTS has no existing value, then prompt for input
::
:again
(SET artist=)
SET /p artist="Artist ? "
::
:: Check for input, exit if none
:: Note :EOF is a special predefined label meaning "END OF FILE"
:: character case is generally insignificant
::
IF NOT DEFINED artist GOTO :eof
::
:: make a new directory
:: the 2>nul suppresses an error message like 'it already exists'
:: In quotes in case variables contain spaces
MD "%destdir%\%artist%" 2>nul
::
:: Now look for filenames containing the data entered
:: Note: here, the metavariable %%i IS Case-sensitive
:: >nul means 'don't show message like '1 file(s) moved'
FOR /f "delims=" %%i IN (
' dir /s /b /a-d "%relroot%\*%artist%*" '
) DO (
ECHO %%i
IF EXIST "%destdir%\%artist%\%%~nxi" (
ECHO Cannot MOVE "%%i" because "%destdir%\%artist%\%%~nxi" exists
) else (ECHO MOVE "%%i" "%destdir%\%artist%\%%~nxi" >nul)
)
GOTO again
Well, here's a starter script - assuming that artists' names are in the filename.
Most of the documentation is in-line.
Note that the ::... form of documentation is actually a broken-label and is inadvisable within loops and parenthesised code generally - use REM there. It is however easier to type and less intrusive
The FOR loop needs a little explanation: much of it can be deciphered with a bit of persistence from the documentation
for /?
from the prompt. But the heads-up is:
for /f reads a "file" line-by-line and applies each successive line to the metavariable after being tokenised between delimiters. You can specify the tokens by number counting from 1 and the delimiters are any characters appearing between the delims= and the closing quote. Default delimiters are [space],[tab],[comma],[semicolon] and default tokens is 1. "delims=" specifies that there are no delimiters, so the entire line is applied to the metavariable.
It's possible to use this facility on a data line like Wed. 07/11/2012 by using FOR/f "tokens=2,3,4delims=/ " %%i in... to apply 07 to %%i, 11 to %%j and 2012 to %%k - the tokens are Wed.,07,11 and 2012 when the line is tokenised using [either space or /] and the 2nd token is applied to the loop metavariable %%i, the third to %%j and so on through the list of token numbers. The special token "*" means 'the rest of the line following the highest-number token nominated'
AND.. a single-quoted "filename" is the output of a command. dir /s /b /a-d "%relroot%\*%artist%*" is the directorylist in /b basic form (filenames only) /s scan subdirectories /a-d but don't mention the war directorynames starting at %relroot% and having %artist% somewhere in the filename - all quoted in case spaces are present.
I wont write it for you but, but here is a list of roughly the things you have to achieve. Try looking for each of those and then combine them
input a name
create a directory with this name
find the files with this name
move found files to the directory
if you post code of what you are trying i'll gladly help you.
I have 500 files coming in and I need to first check if any file(s) exist then rename all of them regardless of what their filename is (the files are named in a different language).
No need to process them in any order.
Rename:
1. “¦X¼d¬f-20110703-¦+¦dñHÑ-ª-¦=¬¦.xls”
2. “¦X¼d¬f-20110707-¦+¡¦-+¡8.xls”
3. “¦X¼d¬f-20110707-¦+¡¦ñj¦«.xls”
4. “¦X¼d¬f-20110708-¦+¡¦¬M¼n.xls”
5. “¦X¼d¬f-20110713-¦d¼O¼n¦hÑP.xls”
.
.
.
500
To:
“TWN_CH_INV_VISIT_FORM_01.xls”
“TWN_CH_INV_VISIT_FORM_02.xls”
“TWN_CH_INV_VISIT_FORM_03.xls”
“TWN_CH_INV_VISIT_FORM_04.xls”
“TWN_CH_INV_VISIT_FORM_05.xls”
.
.
.
“TWN_CH_INV_VISIT_FORM_500.xls”
Hope you could help me on this one. I’ve been trying to do this for weeks.
a simple FOR with a count (SET /A) should do what you need.
setlocal enabledelayedexpansion
SET /A COUNT=0
FOR %%A IN (*.xls) DO (
SET /A COUNT+=1
REN "%%A" "TWN_CH_INV_VIST_FORM_!COUNT!.xls"
)
See HELP FOR and HELP SET
This is a deceptively difficult question to solve.
The 5 year old PA answer has a few problems.
1) The FOR loop begins iterating without buffering the entire directory tree, so it has the potential to rename a file that has already been renamed. I believe that is why the 7 file is missing within r0mmel's comment.
2) Delayed expansion occurs after for variables are expanded, so the file name will be corrupted and the rename will fail if the name contains a ! character.
3) A rename can fail if there already exists a TWN_CH_INV_VIST_FORM_n.xls file with the same number.
At first I thought I could solve the problem using the following:
#echo off
for /f "delims=: tokens=1*" %%A in (
'dir /b *.xls ^| findstr /n "^"'
) do ren "%%B" "TWN_CH_INV_VIST_FORM_%%A.xls.new"
ren *.txt.new *.
I use DIR /B to list the files, and pipe that result to FINDSTR to prefix each file name with a line number, followed by a colon.
I then use FOR /F to iterate and parse the results into the number and the file name. FOR /F buffers the entire result before iterating, so I don't need to worry about renaming the same file twice.
I first give the renamed files a .xls.new "extension", just in case your directory already has files that meet the TWN_CH_INV_VIST_FORM_n.xls pattern. You don't want any name collisions. The final REN command then simply removes the .new extension to leave the desired .xls.
BUT, I just noticed that the original file names have lots of weird characters that could involve unicode that is not in the current code page. FOR /F does not play well with unicode.
There is one other minor issue in that the above does not pad the number to a fixed width. (this could have been solved easily enough)
So at this point it is time to break out my JREN.BAT regular expression renaming utility. It is pure script (hybrid batch / JScript) that runs natively on any Windows machine from XP onward. It has a built in facility to incorporate a fixed width incrementing number in the new name, and it works fine with unicode. I still temporarily give the new name the ".xls.new" extension to avoid any name collisions.
#echo off
call jren "^.*" "'TWN_CH_INV_VIST_FORM_'+$n+'.xls.new'" /j /npad 3 /fm *.xls
ren *.xls.new *.
I chose to pad the incrementing number to 3 digits instead of 2 because the OP said there could be 500 files.
Full documentation for JREN.BAT is available from the command line via jren /?, or jren /?? if you want paged output.