Replace character with windows batch - windows

I get from a FOR loop a variable with drive locations, something like this:
c:\test1
c:\test2
d:\test3 ...and so on
I need to change the c: to c$ so I can map a network drive with the net use
net use k: \\machine\c$\test\

set TEST=c:\test
REM set NEW_TEST=%TEST:x=y%
x is what you want to replace (can be a character or a string)
y is what you want to replace with (can be a character or a string)
Wilds can be used (*)
set NEW_TEST=%TEST:x=y%
echo %NEW_TEST%
c$\test

Related

How to set Batch variable to the volume label of specific drive letter?

I want to write a .BAT file (on Win 10) which gets the volume label of the optical disk mounted at E: and assigns it to a variable so that I can then create a folder on another drive which has the same name as the volume label.
The vol command returns 2 lines of text (with the volume label at the end of the first line). Is there a command which will return the volume label only?
FOR /F "tokens=6" %a IN ('vol c:') DO SET var=%a
This should do. When you run echo %var% it will show the volume label only
Make sure to change the vol c: to your desired volume!
EDIT:
If the Volume label has 2 words, use FOR /F "tokens=6-7" %a IN ('vol c:') DO SET var=%a
If it has 3 words Just change the "tokens=6" to "tokens=6-7,8"
Hope this helps! 😇

Why is this Windows Batch script not able to find the program net.exe?

I'm creating what was meant to be a very simple batch script to map a drive based on user input and check that the drive doesn't already exist first.
#echo off
:EnterInfo
set /P path=Please Enter The Path You Want To Map(EG: \\server\folder)
set /P z=Please Chose A drive Letter To Map.(EG Z)
goto :CheckExist
:CheckExist
%z%:\
pause
if exist %z%:\ (
set /P Sure=A Drive Is Already Using Drive Letter %path%:\ Are You Sure You Want To Replace It?[Y/N]
if /I "%Sure%" EQU "Y" goto :SetDrive
if /I "%Sure%" EQU "N" exit)
goto :SetDrive
:SetDrive
C:
dir
net use z: "%path%"
pause
Here is the code so far.
I'm getting an error:'net' is not recognized as an internal or external command,
when the script gets to the(Net use Z: "%path%")
Although the input to the command would work if i were to run it in a cmd window.
I've checked the location the script and it's running from C:\Users\%username%\ like a cmd box would default it's location too.
I'm really confused as to why it's not recognising net Use. Thanks in advance
The problem is this line:
set /P path=Please Enter The Path You Want To Map(EG: \\server\folder)
The PATH environment variable is already used by Windows. It tells the command interpreter where to find programs like net.exe, which is in your sys(tem32|wow64) folder. You can't just overwrite it as you please and expect everything to work properly afterward. You set the variable PATH to be the network path for the drive you want the user to map, which overwrites the actual PATH variable.
Solution: Use a different variable name, like, say, mypath.

Windows: copy a file until the file not exist

I want to use a Windows batch file in to copy a file (myfile0001.bdg) from one specific directory to another. But I want to check if the file in the target directory exists and if the answer is yes, increment the file with 0001 and check again if the file exists (myfile0002.bdg) and so on, until the file does not exist, and copy the file with the new title.
So, if in the target directory, I have these files:
myfile0001.bdg
myfile0002.bdg
myfile0003.bdg
myfile0004.bdg
myfile0005.bdg
myfile0006.bdg
The new file should be named myfile0007.bdg. The next time I will execute the batch, the new file will be myfile0008.bdg, etc.
I know there is a command "IF EXIST" but I don't know to do what I need.
==============
I'm under Windows 7 x32
The source directory is "C:\USERS\RAMBYTES\DOCUMENTS\"
The target directory is "P:\BACKUP\"
The file is "MYFILE0001.BDG"
Something like this:
#echo off
set source_file=C:\USERS\RAMBYTES\DOCUMENTS\MYFILE0001.BDG
set target_dir=P:\BACKUP\
set done=0
for /l %%i in (1,1,1000) do (
call :check_and_copy %%i
if errorlevel 1 goto :eof
)
goto :eof
:check_and_copy
setlocal EnableDelayedExpansion
set num=000000%1
set fnum=!num:~-4!
set fname=%target_dir%\myfile%fnum%.bdg
rem echo %fname%
if not exist "%fname%" (
echo copying %source_file% to %fname%
exit /b 1
)
exit /b 0
There is no error handling in case there are more than a 1000 files present in the target directory. If you want to increas the file limit, you need to adjust the "main" for loop and the "formatting" of the number in the sub-program
The trick with adding the leading zeros was taken from here: https://stackoverflow.com/a/9430912/330315
#ECHO OFF
SET destdir=c:\destdir
SET newname=myfile0000
FOR /f %%i IN (' dir /b /on %destdir%\myfile????.bdg ' ) DO SET newname=%%~ni
SET newname=1%newname:~-4%
SET /a newname+=1
SET newname=myfile%newname:~-4%.bdg
COPY myfile0001.bdg %destdir%\%newname%
change the destination directory as desired, and include the source directory if required.
Take the file name.
Extract the numeric part.
Check if the corresponding target name exists.
If so,
4.1) increase the numeric part;
4.2) if it doesn't exceed the highest possible number go to Step 3;
4.3) otherwise terminate.
If the target name doesn't exist, copy the file with the current numeric part and terminate.
Although algorithmically the condition in 4.2 may be more natural to be checked just after increasing the numeric part, like I put it above, the below script performs the check at a different point, at the beginning of the loop, which starts just after extracting the original numeric value from the source filename. Implementationally, that seemed to me more convenient.
In all other respects, the script implements the same algorithm:
#ECHO OFF
SET "fname=%~n1"
SET counter=1%fname:~-4%
:loop
IF %counter% GTR 19999 (
1>&2 ECHO Cannot copy the file: no free slots.
EXIT /B 1
)
SET "targetname=%~2\%fname:~0,-4%%counter:~1%%~x1"
IF EXIST "%targetname%" (
SET /A counter+=1
GOTO loop
) ELSE (
COPY %1 "%targetname%"
)
To explain some parts:
The tilde (~) in references to positional parameters means de-quoting of the correspondent parameter.
Sometimes in the script, the tilde is also directly followed by a modifier. Two modifiers are used here, n and x. The former causes the parameter to expand to the corresponding file name only (without the path and the extension) and the latter extract only the extension.
You can learn more about modifier in the built-in of the FOR command (by running
The fname environment variable is needed because extracting of name parts can only be done on environment variables. The %fname:~-4 expression, in particular, evaluates to the last four characters of the fname value. More specifically, it reads: extract the substring that starts at the 4th character from the end and, as -4 isn't followed by another argument, includes all the characters from that point till the end of the string.
Another similar-looking expression, %fname:~0,-4%, does the opposite: it returns the contents of fname except the last four characters. The meaning of the numbers is this: extract the substring that starts at the beginning of the string (offset 0) and spans the range up to and including the character at the offset of 4 from the end.
One more expression of this kind, %counter:~1, extracts the characters starting from the second one (i.e. offset 1) and up to the end of string (no second argument).
Run SET /? to find out more about string expressions.
The counter implementation may also require explanation. The 1 added in front of the numeric part of the file name is needed so that the entire value could be interpreted and processed correctly when incrementing it.
The thing is, a numeric value starting with a 0 is treated as an octal by the CMD command processor, so, putting 1 at the beginning makes it to interpret the number as a decimal, which it actually is. When constructing the complete name of the target file, we simply need to discard the added 1, which is what the %counter:~1 is used for.

how to use dos commands to do following

At the following location
\ncsusnasent02.na.jnj.com\its_diq_na_win_dev\PowerCenter\infa_shared\WCPIT_BIO_EDW\SrcFiles\DDDMD\DDD.CLI026.WK0933.DDDMR45.001.head
I have one file
DDD.CLI026.WK0933.DDDMR45.001.head
if i open this file
i get data as following(in a single line)
HEADER0101IMS HEALTHDMD Weekly D DD.CLI026.WK0933.DDDMR45 Centocor DMDDRM45 W2009080210120090831125325ssnyder#us.imshealth.com
TRAIL0101 000000000581 0000000000CKSUM000002236804730
we need to copy 581(it will not be same always it gets updated everyday) from this file
and put it in a variable
you can try the below. It will set the field into the environment variable id:
for /f "tokens=10" %%a IN (%1) do (
SET id=%%a
)
echo %id%
You can pass the full path and file name into the bat as the first argument.
edit:
This simple bat will take the input from the file you specify on the commandline (param %1), it will use the default separators of <space> and <tab> to break the line in your file - defined in the IN set - into a set of tokens. The "tokens=10" param tells the processor to pass the 10th token, which turns out to be your number in question, into the DO block. It is passed in as a param %%a. Within the DO block, I simply assign that value to an environment variable id. After the for command is complete, I echo the value out to the console.
Take a look at the FOR command, specifically the part about the /F parameter.
I'm not certain enough about the structure of that line to even try to write the full command, but you should be able to write it yourself given that information.
Hmm to me it looks more like the guy needs a dos substr... i.e.
#Echo Off
If not %1.==[]. (Cmd /V:On /C Call %0 [] %1 & GoTo :EOF)
Shift
Set MyVariable=HELLOWORLD
Set ASubStr=!MyVariable:~%1!
Echo [!ASubStr!]
So for example save this as test.bat and then call "test.bat 5" and it will echo WORLD
Google DOS Substring and work out how to parse your text variable the way you want it.

Resolve Windows drive letter to a path (subst and network)

I wonder if there is a universal way of resolving a path using a drive letter (such as X:\foo\bar.txt) into its equivalent UNC path, which might be one of the following:
X:\foo\bar.txt if X: is a real drive (i.e. hard disk, USB stick, etc.)
\\server\share\foo\bar.txt if X: is a network drive mounted on \\server\share
C:\xyz\foo\bar.txt if X: is the result of a SUBST command mapping X: to C:\xyz
I know that there are partial solutions which will:
Resolve a network drive (see for instance question 556649 which relies on WNetGetUniversalName)
Resolve the SUBST drive letter (see QueryDosDevice which works as expected, but does not return UNC paths for things such as local drives or network drives).
Am I missing some straightforward way of implementing this drive letter resolution in Win32? Or do I really have to mess with both WNetGetUniversalName and QueryDosDevice to get what I need?
Here is a batch to translate drive letters to UNC paths or reverse substed paths. Not guaranteed it works though.
Example of use: script.cmd echo Z: Y: W:
#echo off
:: u is a variable containing all arguments of the current command line
set u=%*
:: enabledelayedexpansion: exclamation marks behave like percentage signs and enable
:: setting variables inside a loop
setlocal enabledelayedexpansion
:: parsing result of command subst
:: format: I: => C:\foo\bar
:: variable %G will contain I: and variable H will contain C:\foo\bar
for /f "tokens=1* delims==> " %%G IN ('subst') do (
set drive=%%G
:: removing extra space
set drive=!drive:~0,2!
:: expanding H to a short path in order not to break the resulting command line
set subst=%%~sfH
:: replacing command line.
call set u=%%u:!drive!=!subst!%%
)
:: parsing result of command net use | findstr \\ ; this command is not easily tokenized because not always well-formatted
:: testing whether token 2 is a drive letter or a network path.
for /f "tokens=1,2,3 delims= " %%G IN ('net use ^| findstr \\') do (
set tok2=%%H
if "!tok2:~0,2!" == "\\" (
set drive=%%G
set subst=%%H
) else (
set drive=%%H
set subst=%%I
)
:: replacing command line.
call set u=%%u:!drive!=!subst!%%
)
call !u!
Yes, you would need to resolve the drive letter independently.
WNetGetUniversalName() comes close, but only works for drive letters that are mapped to actual UNC shares, which is not always the case. There is no single API function that does all of the work for you.

Resources