Write variable in quotes to output file - batch-file

(for %%f in (%zipfiles%) do (
<nul set /p ="%%f",
certutil -hashfile "%%f" SHA256|find /v ":" || echo empty file
))> "C:\Location\Report\ListOfFiles.csv"
the "%%f" does not work, neither %%"f" nor "/p =%%f",
What I want is the filename in quotes:
"Filename 001.zip",68b17a9d0d98dd64f3c6c5b29e5cd304a6397d21f24e3087723ccad9f6f77c58

#ECHO OFF
SETLOCAL EnableExtensions
set "zipfiles=*.zip"
(for %%f in (%zipfiles%) do (
<nul set /p =""%%f","
certutil -hashfile "%%f" SHA256|find /v ":" || echo empty file
))>".\ListOfFiles.csv"
Here in <nul set /p =""%%f",":
outer double quotes used to escape the comma as well as inner double quotes so that
inner double quotes and the comma are copied to the output stream.

#ECHO OFF
SETLOCAL
set "zipfiles=file*"
(for %%f in (%zipfiles%) do (
if %%~zf==0 (echo "%%~ff",empty file
) else for /f "delims=" %%a in ('certutil -hashfile "%%f" SHA256^|find /v ":"') do echo "%%~ff",%%a
))> "u:\ListOfFiles.csv"
GOTO :EOF
Simple enough - no tricks. I tried with files named filename* on my machine. Simply use %%~zf for zero-length files to produce that name and otherwise select only the non-:-containing lines for certutil output to build the other lines; ^ used to escape the pipe so the certutil output is filtered.
destination filename also changed to suit my system.

Related

Batch - Read file and search for token

i have a textfile with different values in it.
define Domain "http://xyz.co"
define Remote "https:/www.test.co"
define OUTFILE "Folder name"
...
I would like to read the file and search for special tokens like Domain oder OUTFILE and set the value from the double quotes to a variable. The value inside the double quotes can contain spaces.
for /F "eol=; tokens=*" %%z in ("filename.txt") do (
set value=%%z
ECHO %%z | FINDSTR /C:"Domain" >nul & IF NOT ERRORLEVEL 1 (GOTO ITERATE)
)
:ITERATE
for /f tokens^=2^ delims^=^" %%p in ("%value%") do set Domain=%%p
echo %Domain%
This works so far for one value.
Is it possible to parse only once the file?
Is there a better way to get the content inside the double quotes?
Thanks!
:: Q:\Test\2018\11\01\SO_53101679.cmd
#Echo off&SetLocal EnableExtensions EnableDelayedExpansion
::clear env vars
For %%A in (Domain OUTFILE) do set "%%A="
for /F "eol=; tokens=1,2*" %%A in ('
findstr /i "^define.Domain ^define.OUTFILE" filename.txt
') do Set %%B=%%C
For %%A in (Domain OUTFILE) do if defined %%A Echo %%A=!%%~A!
Sample output based on your above fragment:
> Q:\Test\2018\11\01\SO_53101679.cmd
Domain=http://xyz.co
OUTFILE=Folder name

How to read all content from text flie in single variable in Batch Script?

This is my first experience in batch script, i am trying to read text file content and trying to set its content in single variable i am using .bat file to run script but script not working.
i want to set all content of file in single variable.
tried most of example but failure.
below is my script which i am trying
cd "C:\documents and settings\%USERNAME%\desktop"
for /f "delims=" %%x in (Test.txt) do set Build=%%x
pause >nul
exit
This is my Text File
And
below result is showing
i want it in single variable
cd "C:\documents and settings\%USERNAME%\desktop"
setlocal enableDelayedExpansion
for /f "useback delims=" %%x in ("Test.txt") do set "Build=!build! %%x"
echo %build%
pause >nul
exit
Mind that the max length of a string you can assign to a variable is 8191 symbols.
Also some special symbols could break the script above (%,! ..)
i want to set all content of file in single variable.
In batch, the only way is to construct a multi-line variable yourself, named !LF!
#echo off
SETLOCAL EnableDelayedExpansion
::Change this
set "file=%~f0"
if NOT EXIST "%file%" exit /b 1
::Initialize & empty variables
( set LF=^
%= 0x0D Form Feed =%
)
set "lines="
set "data="
::Count lines
FOR /F tokens^=*^ delims^=^ eol^= %%L in (
'2^>nul findstr /N "^" "%file%"'
) do set /a "lines+=1"
::Read file using SET /P
<"%file%" (
for /L %%a in (1 1 %lines%) do (
set "x=" %= Workaround for empty lines =%
set /p "x="
set "data=!data!!LF!!x!"
)
)
::Print data
echo(!data!
ENDLOCAL
pause & exit /b
The FOR /F tokens^=*^ delims^=^ eol^= disables eol by escaping every delimiter. Warning: "eol=" DOES NOT disable eol, but sets the quote " as the end-of-line character!
Disadvantages:
SLOW: On my machine, it takes 2 seconds for a 2000 lines file, printing the variable excluded
The line ending style (\n or \r\n is ignored, and always set to \n)
Additional \n at the beginning of variable
Advantages:
SAFE: Always works for any file with printable ASCII characters (0x20 ~ 0x7E)
You can also use #dbenham's CERTUTIL method. It is foolproof against <CR> <LF> ! ^...
See more tricks with certutil for the "poorly documented" switches explained in depth.
#echo off
====SETLOCAL EnableDelayedExpansion EnableExtensions
set "B=^!"
set "C=^"
set ^"L=^
%===Line Feed===%
"
for /F %%C in ('wmic qfe list') do set "R=%%C" Carriage Return
>nul 2>&1 certutil -f -encodehex Test.txt "%temp%\hex.txt" 4
pushd "%temp%"
>expand.txt (
for /f "delims=" %%A in (hex.txt) do for %%B in (%%A) do (
set "char=%%B"
REM ! --> !B!
set "char=!char:21=21 42 21!"
REM ^ --> !C!
set "char=!char:5e=21 43 21!"
REM <CR> --> !R!
set "char=!char:0a=21 4c 21!"
REM <LF> --> !L!
set "char=!char:0d=21 52 21!"
echo(!char!
)
)
>nul 2>&1 certutil -f -decodehex expand.txt rawContent.txt
for /f delims^=^ eol^= %%A in (rawContent.txt) do set "fileContent=%%A"
del hex.txt expand.txt rawContent.txt
popd
echo(!fileContent!

Batch file to rename text files within directory with text from within text file at specific line except if line blank

#Echo off&SetLocal EnableExtensions EnableDelayedExpansion
cd "C:\Documents and Settings\John\Desktop\New\Interest\f2"
Pushd "C:\Documents and Settings\John\Desktop\New\Interest\f2"
Set Line#=26
Set /A LOfs=24 -1, Len=34 - LOfs
For %%A in (*.txt) do For /F "tokens=1* delims=:" %%B in (
'Findstr /N ".*" "%%A" ^|Findstr "^%Line#%:"'
) do if %errorlevel% == 0 Set "Line=%%C"&Ren "%%~fA" "!Line:~%LOfs%,%Len%! - %%A!""
Popd
In the above I am trying to change the filename of files in a directory with text in it at a certain position.
If line 26 is blank do nothing and do not change filename.
I have gone wrong somewhere and am going round in circles.
Can anyone help?
Thank you.
You don't state how your script fails, but I can see some potential problems. I also see possible simplifications.
You certainly don't need both CD and PUSHD
I got rid of the numeric variables and included the number literals in the actual code. You can revert back to variables if you want.
You don't need the outer FOR loop. FINDSTR can search multiple files when using wildcards in the file name, and then it will include the filename, followed by : in the output. So if you add the /N option, output will have the form filename:line#:text. You can then adjust the 2nd FINDSTR to return only the correct line numbers.
It is not enough to ignore blank lines. Your rename only works if there is at least one valid file name character after the 23rd character. Filenames cannot include :, *, ?, /, \, <, >, or |. (I may have missed some). I adjusted the FOR /F delims and the FINDSTR search to compensate.
FOR variable expansion like %%A will corrupt values if they contain ! and delayed expansion is enabled. ! is a valid character in file names. So the delayed expansion must be toggled on and off within the loop.
I believe the following will do what you want. The code below will simply echo the rename commands. Remove the ECHO before the ren once it gives the correct results.
#echo off
setlocal disableDelayedExpansion
pushd "C:\Documents and Settings\John\Desktop\New\Interest\f2"
for /f "tokens=1,3 delims=:*?\/<>|" %%A in (
'findstr /n "^" "*.txt" ^| findstr "^[^:]*:26:.......................[^:*?\\/<>|]"'
) do (
set "old=%%A"
set "line=%%B"
setlocal enableDelayedExpansion
ECHO ren "!old!" "!line:~23,11! - !old!"
endlocal
)
popd
An slightly different method to Daves:
#Echo Off
Set "SrcDir=%UserProfile%\Desktop\New\Interest\f2"
Set "Mask=*.txt"
Set "Line#=26"
Set "LOfs=23"
Set "Len=11"
If /I Not "%CD%"=="%SrcDir%" Pushd "%SrcDir%"2>Nul&&(Set _=T)||Exit/B
For /F "Tokens=1-2* Delims=:" %%A In ('FindStr/N "^" "%Mask%" 2^>Nul'
) Do If "%%B"=="%Line#%" If Not "%%~C"=="" (Set "Line=%%C"
SetLocal EnableDelayedExpansion
If Not "!Line:~%LOfs%,%Len%!"=="" (
If Not Exist "!Line:~%LOfs%,%Len%! - %%A" (
Ren "%%A" "!Line:~%LOfs%,%Len%! - %%A"))
EndLocal)
If "_"=="T" PopD
This method don't require findstr.exe nor toggle setlocal/endlocal, so it should run faster. Also, it avoids to re-process any already renamed file changing the plain for %%A by a for /F combined with dir command.
#Echo off
SetLocal EnableDelayedExpansion
cd "C:\Documents and Settings\John\Desktop\New\Interest\f2"
Set /A Line#=26, LOfs=24 -1, Len=34 - LOfs
For /F "delims=" %%A in ('dir /A-D /B *.txt') do (
rem Read the desired line from this file
(for /L %%i in (1,1,%Line#%) do set "Line=" & set /P "Line=") < "%%A"
if defined Line ECHO Ren "%%~fA" "!Line:~%LOfs%,%Len%! - %%A"
)
Note also that when this Batch file ends the current directory is automatically recovered to the current one when setlocal command was executed, so pushd/popd commands are not needed either.

rename a file removing part of the filename batch script

I have some files in the form:
filename1 1 extra1.ext
filename1 2.ext
filename1 3 extra2.ext
...
filename2 1.ext
filename2 100 extra3.ext
...
filename20 1.ext
filename20 15 extra100.ext
(etc.)
...where filename1, filename2, etc., can contain spaces, symbol ' but not numbers. And extra1, extra2, etc, can contain anything. The number in the file name enclosed by spaces does not repeat per same filename1, filename2, etc.
What i want is to remove the extra things of the files that contain it. That is, to get from filename20 15 extra100.ext to filename20 15.ext
My first attempt is this:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "FILE=file name 11 con sosas extras 2.txt"
set "ext=txt"
set "folder=."
for /F "tokens=1,* delims=0123456789" %%A in ("!FILE!") do (set "EXTRA=%%B")
set "FIRST=!FILE:%EXTRA%=!"
set "filename=!FIRST!.!ext!"
echo !EXTRA!
echo !filename!
echo rename "!folder!\!FILE!" "!filename!"
that seems to work, but if i change it to receive parameters, it doesn't:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "FILE=%1"
set "ext=%2"
set "folder=%3"
for /F "tokens=1,* delims=0123456789" %%A in ("!FILE!") do (set "EXTRA=%%B")
set "FIRST=!FILE:%EXTRA%=!"
set "filename=!FIRST!.!ext!"
echo !EXTRA!
echo !filename!
echo rename "!folder!\!FILE!" "!filename!"
where %1 is the filename, %2 is the extension and %3 is the folder in which the files are. Probably, the extension can be extracted inside the batch, but i don't know how to do it.
On another hand, i plan to use this batch into another one. There, there will be a for loop in (*.txt) and i don't know how to differentiate between files that have extra things (and then call this batch) from files that doesn't (and then not call this batch).
Regards,
use your method to extract the "extra-portion". In a second step, remove that extra-portion:
#echo off
setlocal enabledelayedexpansion
set "FILE=file name 11 con sosas extras 2.txt"
for /f "tokens=1,* delims=1234567890" %%a in ("%file%") do set new=!file:%%b=!%%~xb
echo %new%
%%~xb gives you the extension.
Here is a batch script that seeks the first purely numeric string portion enclosed within SPACEs, or in case it appears at the end, preceded by a SPACE, that occurs after some other text not consisting of SPACEs only. The part in front of the found number followed by a SPACE followed by the number itself are used for building the new file name.
This approach handles all valid characters for file names properly, even ^, &, %, !, ( and ).
So here is the code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=.\test"
for /F "eol=| delims=" %%F in ('
dir /B "%_SOURCE%\*.ext" ^| findstr /R /I ^
/C:"^..* [0123456789][0123456789]*\.ext$" ^
/C:"^..* [0123456789][0123456789]* .*\.ext$"
') do (
set "FILE=%%F"
call :SPLIT FIRST NUM REST "%%~nF"
if defined NUM (
setlocal EnableDelayedExpansion
ECHO rename "!_SOURCE!\!FILE!" "!FIRST! !NUM!%%~xF"
endlocal
)
)
endlocal
exit /B
:SPLIT rtn_first rtn_num rtn_rest val_string
setlocal DisableDelayedExpansion
set "RMD=" & set "NUM=" & set "STR=%~4"
:LOOP
for /F "tokens=1,2,* delims= " %%I in ("%STR%") do (
if not "%%J"=="" (
(for /F "delims=0123456789" %%L in ("%%J") do rem/) && (
if not "%%K"=="" (
set "STR=%%J %%K"
goto :LOOP
)
) || (
set "NUM=%%J"
if not "%%K"=="" (
set "RMD=%%K"
)
)
)
)
set "STR=%~4"
if not defined NUM goto :QUIT
set "STR=%STR% "
call set "STR=%%STR: %NUM% =|%%"
for /F "delims=|" %%L in ("%STR:^^=^%") do set "STR=%%L"
:QUIT
(
endlocal
set "%~1=%STR%"
set "%~2=%NUM%"
set "%~3=%RMD%"
)
exit /B
After having tested the script, remove the upper-case ECHO command to actually rename any files.

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