.bat - check for a string in file - batch-file

I have a xml files filles with tabs and spaces. I am trying to search for a string in this file. File is something like below. I am trying to search for </ViewSettings> and this surrounded by tabs and spaces.
<ViewSettings>
<Location>
<X>0</X>
<Y>0</Y>
</Location>
</ViewSettings>
<WorkspaceName="FREE_UST_BETA_UA" PAth="\\mktxindfs\data_configuration\FREE_BETA" IsAdmin="false" />
</Workspaces>
I have the code below
echo off
setlocal enabledelayedexpansion
for %%X in (C:\add\WorkspaceXML\Workspaces.xml) do (
set "reference=</ViewSettings>"
for /f "delims=" %%T IN (%%X) do (
set output=%%T
echo output:!output!
if !output!==!reference! echo found reference.....
)
)
It does not print "found reference"
Thanks

Have you considered building your batch file off of findstr instead? This command would tell you if the string was in the file by reporting the filename.
findstr /M /c:"</ViewSettings>" C:\add\WorkspaceXML\Workspaces.xml
EDIT
If you use findstr /N /O ... instead, you can get the line number and offset of the match(es), maybe that will be of more use to you. The output in your case above would be
6:69:</ViewSettings>
EDIT 2
Proper offset added above thanks to dbenham. Not sure if the offset is still of use to you, but to get both values in vars, try this:
FOR /F "tokens=1,2 delims=:" %%a in ('findstr /N /O /c:"</ViewSettings>" C:\add\WorkspaceXML\Workspaces.xml') do echo %%a %%b
This just displays the vars for you of course, but you can set them as needed.

Related

How to trim string in command prompt?

I have a lot of shortcut urls in a directory.
C:\Users\Owner\Desktop\ReadItLaters>dir *.url /b
aaa.url
bbb.url
ccc.url
...
zzz.url
I want to pickup those url.
so I wrote command like this.
for %i in (*.url) do #type "%i" | find "URL="
that outputs like this.
URL=https://www.example.com/aaa.html
URL=https://www.example.com/bbb.html
URL=https://www.example.com/ccc.html
...
URL=https://www.example.com/zzz.html
It tastes nice. but I want to get url strings WITHOUT "URL=".
I wish to output like this.
https://www.example.com/aaa.html
https://www.example.com/bbb.html
https://www.example.com/ccc.html
...
https://www.example.com/zzz.html
How can I replace "URL=" to empty?
You can use substring, skipping the first 4 characters in your string: %_url:~4%
cmd/bat
for /f %%i in ('type *.url^|find "URL="')do set "_url=%%~i" && call echo/%_url:~4%
command-line
for /f %i in ('type *.url^|find "URL="')do set "_url=%~i" && call echo/%_url:~4%
Some further reading:
[√] Set
[√] For Loop
[√] For /F Loop
[√] Conditional Execution || && ...
[√] Substring in Set command (Refer: %_url:~4%)
use a for /f loop to process the lines:
for /f "tokens=2 delims==" %%a in ('type *.url 2^>nul^|find "URL="') do #echo %%a
or a bit saver (in case the URLs contain =)
for /f "tokens=1,* delims==" %%a in ('type *.url 2^>nul^|findstr /b "URL="') do #echo %%b
See for /? for details.
(Note: this is batch file syntax. If you want to use it directly on the command line, replace each %% with a single %)
You should be able to get the information for multiple URL files, without the need to nest two for loops. You can take advantage of FindStr's ability to search through multiple files directly.
batch-file:
#For /F "Tokens=1*Delims==" %%G In ('""%__AppDir__%findstr.exe" /IR "^URL=http" "*.url" 2>NUL"')Do #Echo %%H
cmd:
For /F "Tokens=1*Delims==" %G In ('""%__AppDir__%findstr.exe" /IR "^URL=http" "*.url" 2>NUL"')Do #Echo %H

Batch - Search for part/exact name and copy line from text file into batch as var

This information below is contained in a text file and formatted as such.
/var/www/xxx/html/videos/video_folder_1
/var/www/xxx/html/videos/video_folder_2
/var/www/xxx/html/videos/video_folder_3
/var/www/xxx/html/videos/video_folder_4
/var/www/xxx/html/videos/video_folder_5
/var/www/xxx/html/videos/video_folder_6
/var/www/xxx/html/videos/video_folder_7
I also have a variable called %file_name% in the batch file already defined.
So lets say that is it is %file_name% = V001-video_folder_6.mp4
As you can see there is some more extra information, V001- and .mp4.
I would like to use the var %file_name% to search the text file and return the entire line. In this case it would return /var/www/xxx/html/videos/video_folder_6 and then put this information in a new var, let us say, %folder_path%.
I think I would use findstr however I have been playing around and not getting the best results.
The problem with the methods that use findstr is that they are slow, because they require to execute findstr.exe (a ~30KB file) each time. A simpler/faster solution is to use just internal Batch commands with the aid of an array. If the number of names to process is large, the difference in time between the two methods may be marked.
#echo off
setlocal EnableDelayedExpansion
rem Load the lines from text file into an array with the last part as index:
for /F "delims=" %%a in (test.txt) do (
set "line=%%a"
for %%b in (!line:/^= !) do set "lastPart=%%b"
set "folder[!lastPart!]=%%a"
)
set "file_name=V001-video_folder_6.mp4"
rem Get the folder from file_name:
for /F "tokens=2 delims=-." %%a in ("%file_name%") do set "folder_path=!folder[%%a]!"
echo Folder path is: %folder_path%
Let us assume the posted lines are in file Test.txt in current working directory.
#echo off
set "file_name=V001-video_folder_6.mp4"
for /F "tokens=2 delims=-." %%A in ("%file_name%") do set "folder=%%A"
for /F "delims=" %%P in ('%SystemRoot%\System32\findstr.exe "/C:%folder%" Test.txt') do (
set "folder_path=%%P"
goto NextCommand
)
:NextCommand
echo Full folder path is: %folder_path%
Open a command prompt window, enter the command for /?, hit key RETURN or ENTER and read output help to understand this little code.
The command goto inside FOR loop results in an immediate exit from loop processing output of findstr.exe after first found line containing the folder path of interest.
Perhaps better in case of searched folder is not found in text file:
#echo off
set "file_name=V01-VIDEOS for school (Miss Patrick).mp4"
for /F "tokens=2 delims=-." %%A in ("%file_name%") do set "folder=%%A"
for /F "delims=" %%P in ('%SystemRoot%\System32\findstr.exe "/C:%folder%" Test.txt') do (
set "folder_path=%%P"
goto FoundFolder
)
echo "%folder%" not found in file Test.txt.
pause
goto :EOF
:FoundFolder
echo Full folder path is: "%folder_path%"
pause
This should work:
::file_name=V001-video_folder_6.mp4
::file containing folder paths is called paths.txt
for /f "tokens=2 delims=-." %%a in ("%file_name%") do set FN=%%a
for /f %%a in ('findstr /E /L "%FN%" "paths.txt"') do set folder_path=%%a
echo %folder_path%
Which does what you want in effectively two lines.

Batch: find files with specific content and extend existing name

I have about 100 .xml files, but its filenames are not self-explanatory. Therefore I would like to look for a specific word and extend the respecting file with this word.
Thanks to some other helpful entries, I could partially figure out how to do this, but somehow the files are not renamed.
Has anybody an idea what is wrong with my code? Thank you in advance.
chcp 1252
SET sourcedir=P:\path
FOR /f "tokens=1 delims=." %%a IN ('findstr /c:"3256" "%sourcedir%\*.xml"') DO (
ECHO (REN "%%a.xml" "%%a_3256.xml")
)
pause
chcp 1252
SET "sourcedir=P:\path"
FOR /f "delims=" %%a IN ('findstr /m /c:"3256" "%sourcedir%\*.xml"') DO (
ECHO REN "%%a" "%%~na_3256%%~xa"
)
pause
In your code you are using %%a for both arguments to ren command, but the second argument must only contain the name and extension, without path. You can solve it using %%~na, that is, the file name (without path or extension) of the file being referenced by %%a (%%~xa is the extension)
Also, if the string is found more than once in any file, your code will try to rename the file twice (or more). It is better to use the /m switch in findstr to only retrieve the list of files.
Rename operations are only echoed to console. If the output is right, remove the echo command.
Dang it MC ND, right after I did some frankenstein scripting, coming up with:
After trial and error along with this great website, I managed to come up with (giving credit to DOS Batch : remove characters from string in a FOR loop )
#ECHO OFF
set pathd=C:\SomePathHere
setlocal enabledelayedexpansion
for /f %%a in ('findstr /ic:SearchString %pathd%\*.xml') do (
set str=%%a
set str=!str:^:=!
echo !str!
)

Replace a character in a file using a batch script

I am new to batch file scripting and need to develop a script to replace a character in a file using a batch script.
I have to replace "servername/ActionService.asmx,1"
with "servername/ActionService.asmx,0"
in file called APP.
Please let me know if there is any solution using only commands.
You can use GNUWin32 sed:
#ECHO OFF &SETLOCAL
set "string=servername/ActionService.asmx,1"
FOR /f %%a IN ('echo "%string%" ^| sed "s/[0-9]/0/"') DO set "newstring=%%~a"
ECHO %newstring%
If you're toggling back and forth between these two states, it might be easier to create two copies of the file with different names, together with a couple of batch files (e.g. actionService1.bat and actionService2.bat) to copy the appropriate file over your APP file.
Otherwise you might consider getting Windows versions of the Unix tools sed and awk, which excel at this type of file manipulation.
The Batch file below assume that there is precisely one line with the target string. This method is relatively fast.
#echo off
for /F "delims=:" %%a in ('findstr /N "servername/ActionService.asmx,1" theFile.txt') do set lineNum=%%a
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" theFile.txt do (
set "line=%%b"
setlocal EnableDelayedExpansion
if %%a equ %lineNum% (
echo !line:1=0!
) else (
echo(!line!
)
endlocal
)) > theFile.new
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:: Way the first - suppresses emptylines
FOR /f "delims=" %%i IN (app) DO SET line=%%i&set line=!line:servername/ActionService.asmx,1=servername/ActionService.asmx,0!&ECHO(!line!
ECHO ====================
:: Way the second
FOR /f "delims=" %%i IN ('type app^|findstr /n "$"') DO (
SET line=%%i
set line=!line:servername/ActionService.asmx,1=servername/ActionService.asmx,0!
SET line=!line:*:=!
ECHO(!line!
)
ECHO ====================
GOTO :EOF
Two ways here. You would need to redirect your choice to a new file as you cannot update in-place.
Doing a quick google search I found this http://www.dostips.com/?t=Batch.FindAndReplace
Using a helper batch file called repl.bat from here: http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
type app |repl "servername\/ActionService.asmx,1" "servername/ActionService.asmx,0" >appnew.txt

DOS batch FOR loop with FIND.exe is stripping out blank lines?

This DOS batch script is stripping out the blank lines and not showing the blank lines in the file even though I am using the TYPE.exe command to convert the file to make sure the file is ASCII so that the FIND command is compatible with the file. Can anyone tell me how to make this script include blank lines?
#ECHO off
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE.exe "build.properties" ^| FIND.exe /V ""`) DO (
ECHO --%%A--
)
pause
That is the designed behavior of FOR /F - it never returns blank lines. The work around is to use FIND or FINDSTR to prefix the line with the line number. If you can guarantee no lines start with the line number delimiter, then you simply set the appropriate delimiter and keep tokens 1* but use only the 2nd token.
::preserve blank lines using FIND, assume no line starts with ]
::long lines are truncated
for /f "tokens=1* delims=]" %%A in ('type "file.txt" ^| find /n /v ""') do echo %%B
::preserve blank lines using FINDSTR, assume no line starts with :
::long lines > 8191 bytes are lost
for /f "tokens=1* delims=:" %%A in ('type "file.txt" ^| findstr /n "^"') do echo %%B
::FINDSTR variant that preserves long lines
type "file.txt" > "file.txt.tmp"
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" "file.txt.tmp"') do echo %%B
del "file.txt.tmp"
I prefer FINDSTR - it is more reliable. For example, FIND can truncate long lines - FINDSTR does not as long as it reads directly from a file. FINDSTR does drop long lines when reading from stdin via pipe or redirection.
If the file may contain lines that start with the delimiter, then you need to preserve the entire line with the line number prefix, and then use search and replace to remove the line prefix. You probably want delayed expansion off when transferring the %%A to an environment variable, otherwise any ! will be corrupted. But later within the loop you need delayed expansion to do the search and replace.
::preserve blank lines using FIND, even if a line may start with ]
::long lines are truncated
for /f "delims=" %%A in ('type "file.txt" ^| find /n /v ""') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*]=!"
echo(!ln!
endlocal
)
::preserve blank lines using FINDSTR, even if a line may start with :
::long lines >8191 bytes are truncated
for /f "delims=*" %%A in ('type "file.txt" ^| findstr /n "^"') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
echo(!ln!
endlocal
)
::FINDSTR variant that preserves long lines
type "file.txt" >"file.txt.tmp"
for /f "delims=*" %%A in ('findstr /n "^" "file.txt.tmp"') do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
echo(!ln!
endlocal
)
del "file.txt.tmp"
If you don't need to worry about converting the file to ASCII, then it is more efficient to drop the pipe and let FIND or FINDSTR open the file specified as an argument, or via redirection.
There is another work around that completely bypasses FOR /F during the read process. It looks odd, but it is more efficient. There are no restrictions with using delayed expansion, but unfortunately it has other limitations.
1) lines must be terminated by <CR><LF> (this will not be a problem if you do the TYPE file conversion)
2) lines must be <= 1021 bytes long (disregarding the <CR><LF>)
3) any trailing control characters are stripped from each line.
4) it must read from a file - you can't use a pipe. So in your case you will need to use a temp file to do your to ASCII conversion.
setlocal enableDelayedExpansion
type "file.txt">"file.txt.tmp"
for /f %%N in ('find /c /v "" ^<"file.txt.tmp"') do set cnt=%%N
<"file.txt.tmp" (
for /l %%N in (1 1 %cnt%) do(
set "ln="
set /p "ln="
echo(!ln!
)
)
del "file.txt.tmp"
I wrote a very simple program that may serve as replacement for FIND and FINDSTR commands when they are used for this purpose. My program is called PIPE.COM and it just insert a blank space in empty lines, so all the lines may be directly processed by FOR command with no further adjustments (as long as the inserted space don't cares). Here it is:
#ECHO off
if not exist pipe.com call :DefinePipe
FOR /F "USEBACKQ delims=" %%A IN (`pipe ^< "build.properties"`) DO (
ECHO(--%%A--
)
pause
goto :EOF
:DefinePipe
setlocal DisableDelayedExpansion
set pipe=´)€ì!Í!ŠÐŠà€Ä!€ü.t2€ü+u!:æu8²A€ê!´#€ì!Í!².€ê!´#€ì!Í!²+€ê!´#€ì!Í!Šò€Æ!´,€ì!Í!"Àu°´LÍ!ëÒ
setlocal EnableDelayedExpansion
echo !pipe!>pipe.com
exit /B
EDIT: Addendum as answer to new comment
The code at :DefinePipe subroutine create a 88 bytes program called pipe.com, that basically do a process equivalent to this pseudo-Batch code:
set "space= "
set line=
:nextChar
rem Read just ONE character
set /PC char=
if %char% neq %NewLine% (
rem Join new char to current line
set line=%line%%char%
) else (
rem End of line detected
if defined line (
rem Show current line
echo %line%
set line=
) else (
rem Empty line: change it by one space
echo %space%
)
)
goto nextChar
This way, empty lines in the input file are changed by lines with one space, so FOR /F command not longer omit they. This works "as long as the inserted space don't cares" as I said in my answer.
Note that the pipe.com program does not work in 64-bits Windows versions.
Antonio
Output lines including blank lines
Here's a method I developed for my own use.
Save the code as a batch file say, SHOWALL.BAT and pass the source file as a command line parameter.
Output can be redirected or piped.
#echo off
for /f "tokens=1,* delims=]" %%a in ('find /n /v "" ^< "%~1"') do echo.%%ba
exit /b
EXAMPLES:
showall source.txt
showall source.txt >destination.txt
showall source.txt | FIND "string"
An oddity is the inclusion of the '^<' (redirection) as opposed to just doing the following:
for /f "tokens=1,* delims=]" %%a in ('find /n /v "" "%~1"') do echo.%%ba
By omitting the redirection, a leading blank line is output.
Thanks to dbenham, this works, although it is slightly different than his suggestion:
::preserve blank lines using FIND, no limitations
for /f "USEBACKQ delims=" %%A in (`type "file.properties" ^| find /V /N ""`) do (
set "ln=%%A"
setlocal enableDelayedExpansion
set "ln=!ln:*]=!"
echo(!ln!
endlocal
)
As mentioned in this answer to the above question, it doesn't seem that lines are skipped by default using for /f in (at least) Windows XP (Community - Please update this answer by testing the below batch commands on your version & service pack of Windows).
EDIT: Per Jeb's comment below, it seems that the ping command, in at least Windows XP, is
causing for /f to produce <CR>'s instead of blank lines (If someone knows specifically why, would
appreciate it if they could update this answer or comment).
As a workaround, it seems that the second default delimited token (<space> / %%b in the example)
returns as blank, which worked for my situation of eliminating the blank lines by way of an "parent"
if conditional on the second token at the start of the for /f, like this:
for /f "tokens=1,2*" %%a in ('ping -n 1 google.com') do (
if not "x%%b"=="x" (
{do things with non-blank lines}
)
)
Using the below code:
#echo off
systeminfo | findstr /b /c:"OS Name" /c:"OS Version"
echo.&echo.
ping -n 1 google.com
echo.&echo.
for /f %%a in ('ping -n 1 google.com') do ( echo "%%a" )
echo.&echo.&echo --------------&echo.&echo.
find /?
echo.&echo.
for /f %%a in ('find /?') do ( echo "%%a" )
echo.&echo.
pause
.... the following is what I see on Windows XP, Windows 7 and Windows 2008, being the only three versions & service packs of Windows I have ready access to:

Resources