I've searched and found several examples on this, but I don't seem to get anything to work... I'm writing a simple Windows batch script to unzip files. In my batch script I have a variable, zipfile, that is dynamically assigned as the most recent Zip file in folder and subfolders:
for /f "tokens=*" %%a in ('dir d:\temp\*.zip /s /b /od') do set zipfile=%%a
To simplify, considering the value:
set zipfile=d:\temp\mysubfolder\myfile.zip
How can I get the full path, "d:\temp\mysubfolder\" ? Thank you!
Easy:
for /f "tokens=*" %%a in ("%zipfile%") do (set fullpath=%%~dpa)
Echo %fullpath%
Done! Make sure %zipfile% does not have surrounding quotes.
Mona
See the call /? for how to use labels inside a batch file.
It also explains how to extract the drive, path, and filename from a parameter.
set zipfile=d:\temp\mysubfolder\myfile.zip
call :SETZIPPATH %zipfile%
goto:eof
:SETZIPPATH
set zippath=%~dp1
You can also do the call from inside the for loop.
Related
I need it to work on Win10 and Win7 machines. If I can get this to work I'll make a batch file.
Winkey, "cmd"
cd "e:\media\trainingvids"
dir *.* /s /b /a -d > c:\temp\dork.txt
So, to state the obvious but make sure I'm getting it, I'm opening a command prompt, changing to the correct directory, doing a directory listing of all files (including sub-directories (/s), no headers or footers so 'bare' format (/b), and trying to NOT display the directory (/a -d) – and then sending/piping that (>) to a file I've designated to be named and created (dork.txt) in a temporary directory (\temp) that already exists on my c:.
The problem is that it doesn't work. I'm not able to find a way to NOT include the full path along with the file names. I need a nudge with the syntax. Or maybe I've got it all wrong and it can't be done in this way.
What does my Basic batch file look like that can do this?
You will need the for /F command to accomplish this:
> "D:\temp\dork.txt" (
for /F "eol=| delims=" %%F in ('
dir /B /S /A:-D "E:\media\trainingvids\*.*"
') do #(
echo(%%~nxF
)
)
You placed a SPACE between /A and -D in your dir command line, which must be removed.
Since I stated the full path to the target directory in the dir command and also to the output file, you can save this script at any location and run it from anywhere.
for /f "delims=" %%a in ('dir /s/b/a-d') do echo %%~nxa
should accomplish that task.
If you can tolerate double quoted names this batch file works well.
set myPath=c:\temp
set myMask=*.pdf
set myLog=c:\temp\myLogFile.log
FORFILES /P %myPath% /S /M %myMask% /C "CMD /C ECHO #file >> %myLog%"
Alter the values to meet your needs.
You're almost there with:
dir /s /w /a-d | find "."
The only drawback is that you get the file names in columns, and possibly a Volume line which you can remove with another find filter.
I need to write a batch script that searches for occurrences of a file named SQLite.Interop.dll in a certain directory. There will actually be many occurrences of this file nested under different subdirectories, and specifically I'd like it to find the one where the folder name is net45.
I started to try and write a batch script myself by piecing together different StackOverflow answers, but ultimately didn't get very far. Here's my initial, feeble attempt:
#setlocal enableextensions enabledelayedexpansion
#echo off
for /r C:\Specified\Directory %%i in (SQLite.Interop.dll) do (set str = %%i & if x%str:net45=%==x%filestr% (copy %%i ./SQLite.Interop.dll & goto BreakStmt)
:BreakStmt
endlocal
Things not yet working:
The Specified Directory path on the for /r statement
Substring searching for net45 in the file path
Not sure if & is the proper way to chain commands?
General syntax... I'm a bit like a fish out of water with this batch stuff...
Use recursive dir /s and filter the output by the directory name surrounded by \, parse the result with for /f:
for /f "delims=" %%a in ('
dir /s /b "C:\Specified\Directory\SQLite.Interop.dll" ^| find /i "\net45\"
') do copy /y "%%a" .
This method doesn't require delayed variable expansion.
Let me set the stage of my issue. I have a folder (FOLDER_ABC). Within that folder, there is a folder for my application, including a unique and always changing version number (application-v1.3.4). Within that folder, there is the application (application-v1.3.4.exe) - which will also change periodically.
C:\FOLDER_ABC\application-v1.3.4\application-v1.3.4.exe
In this section below I create a directory listing of the FOLDER_ABC for any folders starting with application* and store that folder name into a file called directory.txt. I then create a perameter and store that directory into it. I'm doing it this way, versus applying the direct full path to the directory or file, since the versions will change and I don't want to hard code the batch script.
cd C:\FOLDER_ABC\
dir application* /b /ad>"C:\FOLDER_ABC\directory.txt"
set /p verdir= <C:\FOLDER_ABC\directory.txt
Here is my issue. In the section below, I'm trying to get my batch script to run the application*.exe file, and continue on with my batch file. It currently runs my application, but it hangs and doesn't continue the rest of my batch script. I'm really new to all this coding so I appreciate the help. I assume it could be something related to me not closing the FOR loop properly? How can I get it to continue on to :FINISH?
cd "C:\FOLDER_ABC\%verdir%\"
FOR /f "tokens=*" %%G IN ('dir /b *.exe') DO %%G;
:FINISH
ECHO THE END
exit
Figured it out, but didn't have enough StackOverflow credits to answer my own question. My solution is listed below. Thanks everyone. You pointed me in the right direction.
cd "C:\FOLDER_ABC\%verdir%\"
FOR %%G in (*.exe) DO START %%G
you can try:
FOR /f "delims=" %%G IN ('dir /b /a-d *.exe') DO start "" "%%~G"
I'm not sure if this is your problem, but it is possible that the ; is causing problems. You do not terminate commands with ; in batch files.
There is no need for a temporary file. Your code can be greatly simplified with FOR:
pushd c:\folder_abc
for /d %%F in (application*) do cd "%%F"
for %%F in (*.exe) do "%%F"
:FINISH
ECHO THE END
exit /b
Try using the START command:
FOR /f "tokens=*" %%G IN ('dir /b *.exe') DO START %%G;
There may be other better ways if achieving what you want, for example, if you know that the exe always has the same name as its directory, and that there will be only one such directory, you could do the following:
FOR /D %%i in (application-v*) DO START %i\%i.exe
UPDATE
From comments:
My only issue, which I just realized, is that the application folder and application name are not always identical.
In that case, you could try something like:
for /d %%i in (application-v*) do for %%j in (%%i\*.exe) do start %%j
So, I have started with this:
copy | dir /s /b | find "myFile" C:\Destination
but the problem is that the destination is not visible in this command. It only sees the first part of the command up until C:\Destination.
Is there a way I can search for a file and copy it?
I have also tried this:
SET source = dir /s /b | find "myFile"
SET destination = %CD%
copy %file% %destination%
but it doesn't work.
At some point even trying to set a variable that points to the current directory (%CD%) doesn't work.
Thanks in advance!
PS: I'm looking for a solution that would work without installing anything new on the computer, that's why I'm thinking of batch files.
I think I could do this with VBscript but I'm not sure. If anyone thinks it's a better option please post that answer too.
After a few hours of work I have managed to find the right combination of commands in order to make this happen. Here it is for you all and I hope it helps:
SET destination=%CD%
E:
for /f "delims=" %%a in ('dir /b /s ^| find "searchedFile"') do (
cd ..
xcopy "%%a" "%destination%" /D:10-10-2011)
pause
I used the change directory command because the "directory" command returned the entire path, including the file and when trying to copy it.. it thought that the file was in the path that included its name.
For example, if i searched for "myFile.jpg" in "E:\Folder\New Folder\myFile.jpg" it thought that the location of the file was "E:\Folder\New Folder\myFile.jpg\myFile.jpg" and obviously this doesn't work.
dir/s/b|for /f %i in ('find "myFile"') do copy "%i" .\
Works very nicely for me. Anyone know how to use the same line to copy same named files to a directory with new names.
Example:
file name is: text.txt
the above command line searches many folders and copies all instances found like below:
1text.txt, 2text.txt, 3text.txt
Place the file path in quotes
copy "%file%" "%destination%"
or
SET destination = "%CD%"
How about this?
dir/s/b|for /f %i in ('find "myFile"') do copy %i .\
Guess %i should be quoted, too...
dir/s/b|for /f %i in ('find "myFile"') do copy "%i" .\
I need a a windows batch script file to extract the third line from all text files in a directory and output them on a separate text file. Can anyone help me write a batch file to extract this information? I am a rank beginner at this. Thank you!
It is doable, but only with a small hack.
First, you need to create a batch file thirdline.cmd:
#echo off
for /f "skip=2 delims=" %%i in (%1) do echo %%i & goto :EOF
Then, from the command line you would do:
for %i in (*.*) do #thirdline "%i"
If you want to do this from inside another batch file, you 'll need to change the %i above to %%i (i.e. as they appear in thirdline.cmd).
Remember to replace *.* with the filemask that matches the files you want to process.
Finally, thirdline.cmd as given above just outputs the third line to the console. If you want to write it to another file (let's say lines.txt), change thirdline.cmd to:
#echo off
for /f "skip=2 delims=" %%i in (%1) do >>lines.txt echo %%i & goto :EOF
Merely as an alternative, here's another approach:
SETLOCAL
(FOR /L %%i IN (1,1,3) DO SET /P line=) < filename.txt
> another.txt ECHO %line%
ENDLOCAL
Use SETLOCAL & ENDLOCAL whenever you can't be sure if the variables you are going to introduce with your script will not collide with the already existing ones, either defined by the system or brought along by a calling batch script, if any. Basically, use them just to be on the safe side. (Thanks Jon for the suggestion!)
If you have a choice, here's a Ruby for Windows one liner
$ ruby -ne "ARGF.lineno=0 if ARGF.eof?; print if ARGF.lineno==3" *.txt