Extract substring in batch script - batch-file

set line = xxx/yyy/xxx/xxxxxxxx.h:32:#include "../../xxxx/xxxxx.h"
if this is the string, how can i extract just xxxxxxxx.h, between / and : in batch script?
i have included the bin path of cygwin to my windows environment variables so it can run grep commands.
Current, this is my script:
#echo off
SETLOCAL enabledelayedexpansion
set /p search_parameter="Type your search: "
rem run grep seach commmand
grep -nri %search_parameter% --colour --include=*.{c,h} > text.txt
rem filter required lines into new text file
type text.txt | findstr /I "#include" | findstr /V "examples DELIVERY_REL" > text2.txt
rem read text file line-by-line
for /F "tokens=* delims=" %%G in (text2.txt) do (
set "line=%%G"
rem echo line: !line!
for /f "delims=:" %%i in ("!line!") do set "line=%%i"
for %%i in (!line:/= !) do set "line=%%i"
echo line: !line!
)
pause
echo on
Currently, this is my output:
line: line:/
line: line:/
line: line:/
line: line:/
line: line:/
line: line:/
line: line:/
line: line:/
line: line:/
line: line:/
The problem is this line:
for %%i in (!line:/= !) do set "line=%%i"

Use a for /f loop to get the part before the first :.
Then use a plain for to get the last token of this part (tokenize by replacing / with spaces):
#echo off
setlocal
set "line=xxx/yyy/xxx/xxxxxxxx.h:32:#include "../../xxxx/xxxxx.h""
set line
for /f "delims=:" %%a in ("%line%") do set "line=%%a"
set line
for %%a in (%line:/= %) do set "line=%%a"
set line
Output of this code:
line=xxx/yyy/xxx/xxxxxxxx.h:32:#include "../../xxxx/xxxxx.h"
line=xxx/yyy/xxx/xxxxxxxx.h
line=xxxxxxxx.h
due to the exact format of your string, you can just:
set "line=xxx/yyy/xxx/xxxxxxxx.h:32:#include "../../xxxx/xxxxx.h""
for /f "delims=:" %%a in ("%line%") do set "line=%%~nxa"
(Thanks, #dbenham). This works because the parser "translates" the "wrong" slash (not valid for a filename) to the "correct" backslash and %%~nxa just extracts the "filename and extension" from the "full file name". (for treats the string as a filename but doesn't even care, if it's valid)
Edit
...
rem read text file line-by-line
for /F "tokens=* delims=" %%G in (text2.txt) do (
set "line=%%G"
for /f "delims=:" %%i in ("!line!") do set "line=%%~nxi"
echo line: !line!
)

#echo off
SETLOCAL enabledelayedexpansion
set /p search_parameter="Type your search: "
rem run grep seach commmand
grep -nri %search_parameter% --colour --include=*.{c,h} > text.txt
rem filter required lines into new text file
type text.txt | findstr /I "#include" | findstr /V "examples DELIVERY_REL" > text2.txt
rem read text file line-by-line
for /F "tokens=* delims=" %%G in (text2.txt) do (
set "line=%%G"
rem echo line: !line!
for /f "delims=:" %%i in ("!line!") do set "line=%%~nxi"
echo line: !line!
)
pause
echo on

Related

Delete especific lines numbers with batch file

I'm trying to make a script that delete especifics lines of a .txt file by it number. I alreay got it:
#echo off
for /f "skip=1delims=*" %%a in (test.txt) do (
echo %%a >>newfile.txt
) >nul
It works fine and delete the line number '1'. But if i put more lines to delete, it doesn't work, see below:
#echo off
for /f "skip=1,5,8) delims=*" %%a in (test.txt) do (
echo %%a >>newfile.txt
) >nul
What is worong?
as already noted in the comments, skip doesn't help. Instead add line numbers (with find /v /n "") and output the original line (token2) without the line number, if the line number (token1) is not in the list:
#echo off
(for /f "tokens=1,* delims=[]" %%a in ('type test.txt^|find /v /n ""') do (
echo/%%a|findstr /x "1 5 8" >nul || echo/%%b
))>newfile.txt
(findstr switch x is important to compare the whole number, so 2018 isn't found with findstr "1")
|| works as "if previous command (findstr) failed, then"
As suggested findstr and for /f are the tools to use.
I add in conditional execution on fail || or success &&
if findstr does not detect the current line number (produced by the /n option) enclosed in commas in the echoed skip variable the Line is written to newfile.
:: Q:\Test\2018\06\09\SO_50777309.cmd
#echo off
:: generate test.txt with Line1..10
(for /l %%A in (1,1,10) do #Echo=Line%%A) >test.txt
Set "skip=,1,5,8,"
(for /f "tokens=1,*delims=:" %%a in (' findstr /n "^" ^<test.txt'
) do Echo=%skip%|findstr ",%%a," 2>&1>NUL ||Echo=%%b
)>newfile.txt
type newfile.txt
Sample output
Line2
Line3
Line4
Line6
Line7
Line9
Line10
Here is a variant without a pipe (|), which should be faster. Also lines with leading colons (:) or brackets ([/]) should be treated correctly here:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "_FILE=test.txt"
set "_FNEW=newfile.txt"
set "_SKIP=,1,5,8,"
> "%_FNEW%" (
for /F "delims=" %%L in ('findstr /N "^" "%_FILE%"') do (
set "LINE=%%L"
for /F "delims=:" %%K in ("%%L") do (
setlocal EnableDelayedExpansion
if "!_SKIP!"=="!_SKIP:,%%K,=,!" (
echo(!LINE:*:=!
)
endlocal
)
)
)
endlocal
exit /B

findstr /v removing space and dote not working

I have the below batch-file:
cd /d "T:\R\YOU"
for /r T:\R\YOU %%i in (.) do echo %%~nxi>>D:\MultiThreading\ReadFile.txt
cd /d D:\MultiThreading
rem I want to remove dots and spaces for the file content
findstr /v "." ReadFile.pbd >> 11.txt
findstr /v " " 11.pbd >> 12.txt
pause
I am getting the correct output from read file, however the output of 12.txt is empty, what I am doing wrong?
This is the output of ReadFile.txt file:
YOU
YOU 14.1.33333
YOU 14.1.44444
YOU 14.1.55555
YOU 14.1.44444
I want such output (I want to remove the first line):
YOU14133333
YOU14144444
YOU14155555
YOU14144444
The following code snippet read the file ReadFile.txt skipping the first line, removes spaces and dots from every line, and outputs the result into a file called ReturnFile.txt:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
> "ReturnFile.txt" (
for /F "usebackq skip=1 delims=" %%L in ("ReadFile.txt") do (
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LINE=!LINE: =!"
set "LINE=!LINE:.=!"
echo(!LINE!
endlocal
)
)
endlocal
exit /B
#Echo off
For /f "usebackq Tokens=1-10 delims=. " %%A in ("ReadFile.txt"
) Do If "%%B" Neq "" Echo:%%A%%B%%C%%D%%E%%F%%G%%H%%%I%%J
A bit primitive and rather short for answer.

How to read a specified line in a txt file (batch)

I found this line of code on this site that echos a text file line by line:
FOR /F %%i IN (filename.txt) DO echo %%i
I am trying to echo a specific line in the text file. How would I accomplish this?
This method get the desired result in a faster way, especially if the file is large.
#echo off
set "line=100"
(for /L %%i in (1,1,%line%) do set /P "result=") < filename.txt
echo %result%
This will echo line 100.
#echo off
set "var=100"
for /f "tokens=1,* delims=:" %%a in ('findstr /n "^" "filename.txt" ^|findstr "^%var%:"') do echo %%b
Lines starting with : will not be complete.

Bat replace new line char to "|"

I want to replace new line char to "|" use Window bat.
eg file1:
1
2
3
output:
1|2|3
I try this bat:
echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in (123.txt) do (
set a=%%a
set a=!a:"\r\n"=^|!
for %%b in ("!a!") do (
echo.%%~b>>1245.txt
))
pause
But, new line char is not "\r\n". How can I get the new line char expression ?
#echo off
setlocal EnableDelayedExpansion
rem Initialize the output line
set "line="
rem Catenate all file lines in the same variable separated by "|"
for /F "delims=" %%a in (123.txt) do set "line=!line!|%%a"
rem Show final line, removing the leading "|"
echo !line:~1!>>1245.txt
You can play with this a little bit:
FOR /F "Usebackq Tokens=*" %%# IN ("File.txt") DO (
<NUL Set /P "=%%#"
)
or this, the /p removes the newLines:
C:\> echo Hello World
Hello World
C:\> echo|set /p=Hello World
Hello World
with a some edits of Krekkon's script:
#echo off
FOR /F "Usebackq Tokens=* delims=" %%# IN ("123.txt") DO (
echo|set /p=%%#^^^|
)>>temp.file
move /y "temp.file" "123.txt"

How to replace Strings in Windows Batch file

I would like to replace the following String in a file:
android:versionName="anyStringHere" >
*anyStringHere represents any possible string
With:
android:versionName="1.04.008" >
How would I do this in a clean, reusable way, and preserve the new lines, tabs, and indentation in the file?
Not even close to the fastest option, and not 100% bulletproof, but this is pure batch and will handle spacing and indentation while do the replacement.
#echo off
setlocal enableextensions disabledelayedexpansion
rem File to process
set "file=data.txt"
rem How to find lines
set "match=public static String CONST = \"abc\";"
rem String to replace and replacement
set "findStr=abc"
set "replaceStr=def"
rem temporary file to work with lines
set "tempFile=%temp%\repl.tmp"
rem All the output goes into the temporary file
(
rem Process input file extracting non matching lines
for /f tokens^=^1^*^ delims^=^:^ eol^= %%a in ('findstr /n /v /c:"%match%" ^< "%file%"') do (
set /a "n=1000000+%%a"
setlocal enabledelayedexpansion
< nul set /p "n=!n!"
endlocal
echo :%%b
)
rem Process input file extrancting matching lines and changing strings
for /f tokens^=^1^*^ delims^=^:^ eol^= %%a in ('findstr /n /c:"%match%" ^< "%file%"') do (
set /a "n=1000000+%%a"
set "data=%%b"
setlocal enabledelayedexpansion
set "data=!data:%findStr%=%replaceStr%!"
echo !n!:!data!
endlocal
)
)> "%tempFile%"
rem Sort the output file to get the final file
(for /f tokens^=^1^*^ delims^=^:^ eol^= %%a in ('sort "%tempFile%"') do (
if "%%b"=="" (
echo.
) else (
echo %%b
)
)) > "%file%.repl"
This is the simplest way to do this that I could come up with. It takes a String and searches for it in a file, then replaces the entire line that contains the string. It won't only replace parts of a line, which can be done with a bit more effort.
#echo off
:: file containing string to replace
set file=test.txt
:: string to replace in file
set searchString=line 4
:: string to write to file
set repString=line 4 edited
setLocal enableDelayedExpansion
set count=0
if not exist %file% echo cannot find file - %file% & goto :EOF
:: Search for string - and get it's line number
for /F "delims=:" %%a in ('findstr /N /I /C:"%searchString%" "%file%"') do set searchLine=%%a
if not defined searchLine echo cannot find string - %searchString% - in file - %file% & goto :EOF
:: Read file into variables - by line number
for /F "delims=~!" %%b in ('type %file%') do (
set /a count=!count!+1
set line!count!=%%b
)
:: Edit the one line
set line%searchLine%=%repString%
:: Empty file and write new contents
del %file%
for /L %%c in (1,1,!count!) do echo !line%%c!>>%file%
pause
You can change the echo on the last for loop to output to a different file, maybe %file%.new or something, and then remove the del command.
This is a robust solution that retains all formatting. It uses a helper batch file called repl.bat - download from: https://www.dropbox.com/s/qidqwztmetbvklt/repl.bat
Place repl.bat in the same folder as the batch file or in a folder that is on the path.
type "file.txt" | repl "(public static String CONST = \q).*(\q.*)" "$1def$2" x >"newfile.txt"
I found that using sed was the cleanest solution
http://gnuwin32.sourceforge.net/packages/sed.htm
sed "s/android:versionName=\".*\" >/android:versionName=\"%NEW_VERSION%\" >/g" %ORIG_FILE_NAME% > %TEMP_FILE_NAME%
#move /Y %TEMP_FILE_NAME% %ORIG_FILE_NAME% >nul

Resources