I'm making a batch that edits a document, but in order to edit, it need's to CD it its location. The problem I'm having is that in order to make it portable, I need the command to be able to locate the file's location.
I've tried:
CD C:\Users\%username%\AppData\Roaming\skype\John
CD C:\Users\%username%\AppData\Roaming\skype\%foldername%\config.xml
Any way to get to the location with the config.xml?
You can try with:
FOR /D %%G IN ("%APPDATA%\skype\*") DO IF EXIST "%%~fG\config.xml" (
set correctDir=%%G
goto :foundFile
)
echo File config.xml not found
goto :eof
:foundFile
cd "%correctDir%"
FOR /D iterates over all directories using the %%G variable. %%~fG expands to the full path to the directorie in %%G.
IF EXIST checks if a file exists.
goto :eof exits the script
EDIT: As #Compo pointed out: for portability reasons it is better to use the OS built-in environment variable %APPDATA% instead of C:\Users\%username%\AppData\Roaming.
Related
Can anyone here give me a hint, why my batch script marks successfully processed folders as system, hidden, non-archive? Furthermore I cannot even remove the "hidden" attribute via Explorer (probably because of the systemfolder attribute).
The script is meant to process one folder (passed to it as a parameter), looking for raw-photo files (.nef files in my case) that are marked read-only. For every read-only photo the script copies a specified file to the processed folder and renames that copy according to the photo filename.
The folder attribute mess is caused by robocopy. (Without that command there is no problem.) But it doesn't have to touch the folder at all. It only copies one file to that folder. The error only occurs, if at least one file in the folder was marked read-only and gets a sidecar file.
I already tried to move the script from system drive to desktop and start it from there. It made no difference.
(To avoid confusion: I am on a non-English Windows 10, so I used !var! instead of %var%. Hell it took some time to find that trick...)
echo off
setlocal ENABLEDELAYEDEXPANSION
chcp 65001
IF "%~1" == "" (
GOTO myWarning
) ELSE (
IF EXIST "%~1" (
GOTO myFuction
) ELSE (
GOTO myWarning
)
)
GOTO myFuction
:myWarning
echo Ordner-Pfad muss angegeben werden!
pause
GOTO:eof
:myFuction
echo Bearbeite %1
cd "%1"
for /r %%f in (*.nef) do (
set fileattr=%%~af
set readonlyattr=!fileattr:~1,1!
:: check if current file is read-only
IF !readonlyattr!==r (
:: create XMP-Sidecar file for read-only photos
echo %%f
robocopy "C:" "%1" "metadata-2stars.xmp"
rename "metadata-2stars.xmp" "%%~nf.xmp"
)
)
GOTO:eof
Sorry, after I narrowed the problem down to robocopy I found the solution. It seems to be a known bug in robocopy, e.g. described here:
https://blog.coeo.com/how-to-prevent-robocopy-from-hiding-your-files-and-how-to-fix-it-when-it-does
The solution/hotfix is simply to tell robocopy not to mark the destination as system hidden by adding /A-:SH at the end of the command. So with robocopy "C:" "%1" "metadata-2stars.xmp" /A-:SH everything works as expected.
I'm having trouble making a batch file that copies files. Sometimes it says that the directories exist, other times it says that it can not perform a cyclic copy.
#ECHO off
ECHO Please use quotes with directories
ECHO.
IF NOT EXIST Pictures (MD Pictures) > NUL
:start
SET /P From=Copy from:
IF NOT EXIST %From% (ECHO No such directory
ECHO.
goto start)
XCOPY /s %From% Pictures
pause
This is another way to do it: xcopy creates the folder by itself and the slash at the end of the target path stops it from prompting you.
The slash at the if exist "folder\" is used to detect a folder on a local drive, and not a file.
Stephan's answer tells you how to avoid a cyclic copy error.
#ECHO off
ECHO Please use quotes with directories
ECHO.
:start
SET /P From=Copy from:
IF exist "%From%\" (
XCOPY /s %From% "Pictures\"
) else (
ECHO No such directory
ECHO.
goto start
)
pause
if you try to create a directory, that already exists, md tells you. You can suppress it with
md pictures 2>nul
The parameter /s with xcopy tells the computer to copy subdirectories and their content too. So you would make a copy of a copy of a copy of a copy.... (called cyclic copy). To avoid this, don't use /s or make sure, the destination directory is outside the directory-tree, you want to copy.
I want to replace the content paths defined into the file i.e logging.properties to the desired location path of the jboss7 location .
Basically i'm using installer where i have to browse my jboss7 folder and locate it to any desired location of the user . But in few files of jboss7 there are some hardcoded path defined like in given logging.properties file.
I need to change that hard coded path to the desired location path.
As of now i'm having repl.bat and file test.bat files in the same folder.
repl.bat helper file could be find in following link:-
http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
I just copied the code and created repl.bat file.
test.bat file :-
#ECHO OFF
SETLOCAL
SET "folder="
FOR /r "C:\" %%a IN (tintin.txt) do IF EXIST "%%a" SET "folder=%%~dpa"&GOTO got1
FOR /r "D:\" %%a IN (tintin.txt) do IF EXIST "%%a" SET "folder=%%~dpa"&GOTO got1
:got1
echo "%folder%"
PAUSE
set "newpath=%folder%"
set "newpath=%newpath:\=\\%"
echo "%newpath%"
PAUSE
type "logging.properties" | repl "(Directory=).*(\\\\standalone\\\\)" "$1%newpath%$2">"logging.properties.tmp"
PAUSE
move "logging.properties.tmp" "logging.properties"
PAUSE
GOTO :EOF
PAUSE
Here in this test.bat file , i'm searching a file tintin.txt file and setting the path into a variable name as 'folder'. tintin.txt file is just inside the folder of jboss7.This is because of the possibilities of more than one jboss7 application server folder into the system.
Till now i have got the path i.e "C:\Users\Anuj\Desktop\jboss7\" and set into the variable 'folder'.
Now there is file named logging.properties into the folder location
C:\Users\Anuj\Desktop\jboss7\standalone\configuration
logging.properties :-
com.latilla.import.uploadDirectory=C:\\progra~2\\Latilla\\C4i\\jboss7\\ standalone\\uploads
com.latilla.import.maxFilesUploadNumber=10
com.latilla.export.templateFile=C:\\progra~2\\Latilla\\C4i\\jboss7\\standalone\\templates\\GDV_HDI_Format.xls
com.latilla.etl.pluginsRootDirectory=C:\\progra~2\\Latilla\\C4i\\jboss7\\standalone\\cloverETL\\plugins
com.latilla.etl.templatesDirectory=C:\\progra~2\\Latilla\\C4i\\jboss7\\standalone\\etl
com.latilla.db.user=postgres
com.latilla.db.pass=password
repl.bat helper file helps to replace the url path with the desired path i.e path set to variable name 'folder'.
I want to replace the C:\progra~2\Latilla\C4i\jboss7\ with the path set to variable name 'folder'.
Note :-
here in logging.properties file path contents is having different format of path i.e C:\
means double slash. \
Might be the script that i have tried test.bat is incorrect.
When i double click the test.bat file i got error.
Although I can't help you with fixing the issue you are getting while using the repl.bat file, I can suggest a different way of solving the initial problem of path replacement.
If the jboss7 string is guaranteed to be present in all the original paths in your configuration file(s), you could try the following approach:
#ECHO OFF
SETLOCAL DisableDelayedExpansion
FOR /F "delims=" %%A IN ('DIR /B /S C:\tintin.txt') DO (CD /D "%%~dpA" & CALL :got1)
FOR /F "delims=" %%A IN ('DIR /B /S D:\tintin.txt') DO (CD /D "%%~dpA" & CALL :got1)
GOTO :EOF
:got1
SET "propfile=%CD%\standalone\configuration\logging.properties"
IF NOT EXIST "%propfile%" GOTO :EOF
SET "tempfile=%TEMP%\logging.properties.tmp"
FIND /I /V "jboss7\\" >"%tempfile%"
>>"%tempfile%" (
FOR /F "tokens=1,* delims=" %%I IN ('FIND /I "jboss7\\"') DO (
SET "pathname=%%J"
SETLOCAL EnableDelayedExpansion
IF NOT "!pathname!" == "!pathname:*jboss7\\=!" (
SET "pathname=%__CD__:\=\\%!pathname:*jboss7\\=!"
)
ECHO %%I=!pathname!
ENDLOCAL
)
)
ECHO Old file "%propfile%":
TYPE "%propfile%"
ECHO =======================================
ECHO New file:
TYPE "%tempfile%"
PAUSE
:: uncomment the next line once you have verified the replacement works correctly
::MOVE "%tempfile%" "%propfile%"
Searching for the tintin.txt file has been changed slightly so as to possibly make the process faster. Instead of iterating over every directory and checking if it contains the file, the loops now read the output of DIR, which returns only actually existing entries.
Note that you could also use a FOR /R loop, as in your present code, with the same effect i.e. returning only existing paths, but the IN clause would need to contain a mask rather than a normal name, but that would have to be a mask that couldn't match anything else in your system than just tintin.txt. For instance, if you knew for certain that there could be no file called tintin.txt1 or tintin.txtx or anything else where tintin.txt is followed by exactly one character, you could use the following template instead:
FOR /R "C:\" %%A IN (tintin.txt?) DO (CD /D "%%~dpA" & CALL :got1)
and same for D:\. That would return only references to files actually existing and matching the mask.
Also, you can see that the loops do not jump (GOTO) to the got1 label but instead call the got1 subroutine. With that change, it is possible to process many application instances in one go. I don't know yours can be installed multiple times. If not, you'll probably want to change it back to GOTO.
The subroutine in my script is referencing the config file using its full path as specified in your description (...\standalone\configuration\logging.properties). For some reason, in your script the file is referenced simply by its name, even though there's no preceding CD or PUSHD command changing the current directory to the location of the file. I assumed you were trying to simplify your script and omitted that bit, whether intentionally or not. Otherwise I may have missed something in your explanation and/or script.
After verifying that the config file exists at the expected location, the replacement itself is done in this way:
All the non-path config lines are written to a temporary file with one go.
Every config line containing a path is processed in this way:
if it does not contain the jboss7\\ string, it is omitted;
otherwise the part of the path up to and including jboss7\\ is removed;
the current directory is inserted before the remaining part (after every \ is replaced with \\);
the new value is put back into the config line;
the update line is added to the same temporary file.
The old version is of the configuration file replaced with the new one.
Obviously, the script may change the order of lines in the processed file, but it is assumed that that doesn't matter.
I have written the following batch script, which runs another batch script on a directory, or, with addition of a flag, on a directory tree and then on an equivalent directory or directory tree on a different drive (Z:). No matter which option I choose, it outputs the error "The system cannot find the path specified." It does do what it's supposed to if I do it on just one directory, even though it gives the error. It doesn't work successfully on a directory tree. I've run it without #echo off to try understand where its failing, without success. The directory which it's trying to change into does exist.
#echo off
set origdir=%CD%
if X%~f1==X (
echo Please input a directory.
goto done
)
chdir /d %~f1
for %%X in (myotherscript.bat) do (set FOUND=%%~$PATH:X)
if not defined FOUND (
echo myotherscript is not in your PATH
)
if X%2==X/R (
goto recursive
) else ( goto single )
:recursive
for /d /r %%G in (.) do call myotherscript
echo Z:%~p1
chdir /d "Z:%~p1"
for /d /r %%G in (.) do call myotherscript
goto ended
:single
call myotherscript
echo Z:%~p1
chdir /d "Z:%~p1"
call myotherscript
goto ended
:ended
chdir /d origdir
goto done
:done
pause
Here is "myotherscript" Yes, purge does exist.
#echo off
if exist "D:\path\to\purge.bat" (
call purge
for %%f in (*.log.*) do call :renameit "%%f"
for %%f in (*.drw.*) do call :renameit "%%f"
for %%f in (*.asm.*) do call :renameit "%%f"
for %%f in (*.prt.*) do call :renameit "%%f"
goto done ) else (
echo Purge does not exist.
goto done )
:renameit
ren %1 *.1
:done
Any help would be appreciated.
Thanks
I'm not sure why this (very old) question got reactivated. But since it has, let's see if we can close this out.
There seem to be two problems here. First:
it outputs the error "The system cannot find the path specified."
This looks like a simple typo on this line:
chdir /d origdir
Without the '%' marks, this is trying to change to a directory literally named origdir, rather than the original directory the script was run from, which would be:
chdir /d %origdir%
Second problem is:
It does do what it's supposed to if I do it on just one directory, even though it gives the error. It doesn't work successfully on a directory tree.
At a guess, this is due to this line:
if X%2==X/R
"IF" is case sensitive. If you tried to run this using /r, it wouldn't see the request for recursion and would always execute single.
For me I got the "The system cannot find the path specified" due to a missing exe that seemed way later in the script. It seems that the pipes in DOS don't always output data in the order of execution. I was used to UNIX where the output from each "echo" command in a script goes in order, so I had added debug output in the .bat file to try to tell me what lines had executed.
The problem is, the error about the file not found was happening in the output log (and screen) way earlier than the echo commands would indicate. So I don't know if the WinXP cmd shell was going a few steps ahead, or it was parsing for the exe to call during startup of the called bat file or what.
It turned out it was in fact a bad path to the .exe I was running from a call'd bat script, but the echo debug statements made me think I was in a way earlier part of the script. Once I added the right path before the exe it all worked
I am facing error when i try to delete a file using a batch file.
For example say the file i want to delete is "C:\test\a.dll"
i get the folder "c:\test" from registry and then i try to append the file name using and delete it using the following command
del /s %WPINSTDIR%\a.dll
where i get WPINSTDIR from registry and it would be "C:\test"
however when i try to run the batch file i get a error saying network path found
and this is the command that is executed.
del /s "c:\test"\a.dll
By setting a environment path variable i found that the problem is with the 2 slashes in "c:\test" and the quotes. Anyway to get around this problem.
Thanks
Try using
pushd %WPINSTDIR%
del /s a.dll
popd
This restores the former directory.
You can remove quotes around your environment variable with the following:
%WPINSTDIR:"=%
So the following might work:
del %WPINSTDIR:"=%\a.dll
It will fail, though, if the path contains spaces.
You can also use the following:
call :del_file %WPINSTDIR% a.dll
goto :eof
:del_file
del "%~1\%~2"
goto :eof
which should work even with paths containing spaces. The ~ in %~1 removes surrounding quotes.
This might do:
set current=%CD%
CD /d %WPINSTDIR%
DEL /s a.dll
CD /d %current%
EDIT
Edited to use CD /d and the "%CD%-trick".