Issue with simple quote in bat file - command-line

I am trying to execute bat file containing a loop.
When executing a loop, the file execution is aborted.
I modified a little the command to understand what is the error and it seems I cannot put simple quote into the loop.
/f "tokens=1,2 delims==" %%i IN ("version=X.Z.W") do set VERSION=%%j -> success
/f "tokens=1,2 delims==" %%i IN ('version=X.Z.W') do set VERSION=%%j -> failure
It is annoying as version=X.Z.W should be returned by findstr /B /c:"%var%=" ..\..\file.properties
I tested on different desk, and this issue occurs only on my computer.
Do you know if there is any settings to modify?
I have the issue when typing the command directly into a command prompt.
Thanks a lot for your help.

If you are typing the above directly into a command prompt, it will fail because you have used %% instead of %. Windows CMD doesn't read %% as it does processing a batch file.
And the ' as opposed to " are read differently by CMD. ' is read as a command where " is read as a literal string.

Related

Powershell in Batch file: Errors and Commands not executing

Below you can find the content of the two example text files I will use, example1.txt and obf_example1.txt. The latter one contains the string of example1.txt at the end of the file but has some obfuscated strings before.
example1.txt:
adasdkasdaksdasdkjlasdjasndjasd.
obf_example1.txt:
ŠxpÃÒ²Ø-Gêÿ ój"f>ïí H€À(ø4$/+#6Ni9Pvü¶ |CF CÀ¾ý~ª-°à9ÉOÿ V[o¦.E…-Š ƒ9Ú\žê*D´ß()^“£¹ìÅjXÑÍ¥â(¨µ×d'«P|I*èSººº&)Ø|̉ òÔ®¥Ô$LÁ:9ŠLá{¶nZÒبNÙÀØŒ‹0õ´Sék›áÇÉîÆbËF§BЄƒöZKaÒR ²°ÅšDn?+¶()IªP›$ÇEv©¡k€[ßè¨×q-Ëk!µTóPA²—: A ?ÉEEEGÐJúÌ©ÒWµHB¡aäXû|ÓË BPÁwr„Ûi¥åܺÈQ÷ORàSb,Šv¢D ,Žb’(2 öb¢wtKzíĦ#ï¯u©²Ù aîR隬ëÌTbà÷¥3ÄtSGì´R$)X Šù
'¹¨D³ÞeOK3!{·‹¦cäиNÅô:Na1žAÇ1ø8 &Fuôë %¸T¯_òMå†C"ý¤F ™º„Iµºí4Ü¡ˆc!ì•+3 ‰‹M K#JÁ«8¢bsL†!Ù“à­šn·öMå•Œ&ýèvÀ}¨?¦hùÊò(É#Žf~5‰‘qØçþƒ‰Å²ÓÖÊJU•âNWÁ«L¼Y”$G¢ßè&§ÖÉØŒS‘WàË„°SØW Ð¨´_è%‚Å¢ø.ãÃð”#X^þ*1þ‚q85¡lÒ‚Ò>‘¸ÿ £ôQôz#ø¤ÎõÚªï|Xö%;åÍËûGú+îUƒö³‰›p U±Ò ðtÜGÜÿ  ð,åXÿ k8È I”ÿ “½¿Ð`¨u5=SÓqyFÈ É8ôã¨ð£è6’H#lÄI10‚Ö§ÑdµÖ?t¡]D†9Zj,¥EɺÜEq¤#,ìn—¢º‚´€bc·ú¨Lû£ÿ Ó×ÿÙ||adasdkasdaksdasdkjlasdjasndjasd.
When I ran the following powershell command for example.txt in a batch file, it works and I get the output of example.txt:
#echo off
for /f "delims=" %%a in ('powershell Get-Content .\example.txt') do set _output=%%a
echo %_output%
adasdkasdaksdasdkjlasdjasndjasd
Good so far.
However, when I ran the above powershell command for obf_example1.txt, it does not work and I get the following error message:
'¹¨D³ÃzeOK3!{·â?¹Â¦cäÃ?Â?¸Â?NÃ.ô:Na1žAÃ╬1ø8
The command "FuôëÂ" is either misspelled or could not be found.
The command "ýèvÃ?}¨?¦hùÃSÂ?ò" is either misspelled or could not be found.
Why? Never mind I thought: As I am only interested in the last n characters both in example1.txt and obf_example1.txt accordingly, my idea was to extract the last n characters and check if I can see the output of obf_example1.txt then. To check if my idea works, I run the following command for example1.txt to get the last 4 characters as an example:
#echo off
for /f "delims=" %%a in ('powershell $a=Get-Content .\example.txt; $a.substring^(0,$a.length-4^)') do set _output=%%a
echo.%_output%
It doesn't show me anything though. %_output% seems to be empty. How to fix that? And will the fixed version work for obf_example1.txt as well so that I get an output there instead of the above error message?
Apparently, the piece of text you are after is behind the ||.
With PowerShell you can easily get that by using
((Get-Content 'D:\Test\obf_example1.txt' -Raw) -split '\|\|')[-1]
Returns
adasdkasdaksdasdkjlasdjasndjasd
Isn't htis what you want?
You could try reading the last 4 bytes, if you really are taking text characters from what is clearly not a text file. (My guess is that it is text hidden inside a binary file, probably a graphic file).
#For /F Delims^=^ EOL^= %%G In (
'%__AppDir__%WindowsPowerShell\v1.0\powershell.exe -NoP^
"$f=[IO.File]::OpenRead('C:\Users\Ferit\Desktop\obf_example1.txt');"^
"$f.Seek(-4,[System.IO.SeekOrigin]::End)|Out-Null;$buffer=new-object Byte[] 4;"^
"$f.Read($buffer,0,4)|Out-Null;$f.Close();"^
"[System.Text.Encoding]::UTF8.GetString($buffer)"')Do #Set "_output=%%G"
#Set _output 2>NUL&&Pause
Don't forget to modify the text file path, (on line 3), and the three instances of 4 if you want more or less bytes. The last line is included just to show you the output, (you would obviously replace that with your own code).
The following works for me to get the "clear-text" part after || (from your example):
for /f "delims=" %%a in (.\obf_example1.txt) do set "_output=%%a"
set _output
echo testing last 10: %_output:~-10%
set "_output=%_output:*||=%"
set _output
echo %_output%
(it might not work with different encodings of the text file)
(Consider Powershell - cmd has a limit on line length and can easily be overwhelmed)

How to write STDOUT/STDIN via RedMon/cmd.exe to file?

I am trying to redirect a PS output to a file and process it further.
For this I am using the Printer Port Redirection RedMon which is sending the output to CMD.exe
C:\Windows\system32\cmd.exe
As arguments I expected that something like the following should work, but it does not. "%1" contains the user input for filename.
/c >"%1"
or
/c 1>"%1"
or
/c |"%1"
or
/c > "%1" 2>&1
What almost works if I send the output to a batch file which writes it then to file.
/c WriteOutput.bat "%1"
However, the batch file is somehow altering the file (skipping empty lines, and ignoring exclamation marks and so on...)
If possible I want to avoid a batch file. Is there a way to get it "directly" to a file?
Select "Print to FILE" in the printer options is not an option for me. I want the same end result but via cmd.exe being able to process it further.
Any ideas?
Edit:
Well, that's the batch file I used. It neglects empty lines and space at the beginning.
#echo off
setlocal
set FileName=%1
echo(>%FileName%.ps
for /F "tokens=*" %%A in ('more') do (
echo %%A>>%FileName%.ps
)
Well, so far I still haven't found a direct way to write STDIN via RedMon via CMD.exe to a file. As #aschipfl wrote, all the versions with for /F will skip lines and ignore certain characters.
However, with the following batch script (via RedMon) I end up with a "correct looking" file on disk.
C:\Windows\system32\cmd.exe /c WritePS.bat "%1"
"%1" contains the user input for filename without extension.
The Batch-File WritePS.bat looks as simple as this:
#echo off & setlocal
set FileName=%1.ps
more > "%FileName%"
However,
the resulting Postscript file is different from a file which I "Print to FILE" via the Postscript-Printer setup. I am pretty sure that all the printer settings which I can set are the same in both cases.
If anybody has an idea why there might be a difference, please let me know.

Does tag in cmd affect the output of program?

This is just a simple question.
There are the following two lines of codes:
taskkill /F /IM notepad.exe
and---
taskkill /IM notepad.exe /F
In my test, it doesn't matter.
But in other languages / program, WILL IT MATTER?
There is no universal standard for parsing command line arguments. Each command/program is free to establish its own rules for parsing arguments. Some programs or commands require switches to be in specific places. Some don't care.
The DIR internal command allows switches to be placed anywhere and yield the same result.
The FINDSTR external command requires all switches to be at the beginning.
The COPY command allows the /A and /B switches to be anywhere, but with different meanings. Placing /A or /B at the beginning establishes a default format; after a source file name specifies the format for the preceding file; after the target establishes the format for the target.

MS DOS edit a file

I am writing a batch script which I wish to open a file and then change the second line of it. I want to find the string "cat" and replace it with a value that I have SET i.e. %var% . I only want this to happen on the second line (or for the first 3 times). How would you go about doing this?
I just solve it myself. It will lookup var on line two only.
#echo OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET filename=%1
set LINENO=0
for /F "delims=" %%l in (%filename%) do (
SET /A LINENO=!LINENO!+1
IF "!LINENO!"=="2" ( call echo %%l ) ELSE ( echo %%l )
)
But I prefer using cscript (vbscript or even jscript).
First of all, using a batch file to achieve this, is messy (IMHO). You will have to use an external tool anyway to do the string replacement. I'd use some scripting language instead.
If you really want to use a batch, this will get you started.
This would be ugly to do with native batch scripting. I would either
Do this in VBScript. If you really need this in a batch file, you can call the VBScript file from the batch script. You can even pass in %var% as an argument to the VBScript.
Use a sed script. There are windows ports of Unix commands like GnuWin32, GNU Utilities for Win32 (I use these), or Cygwin.
I would create a script that would:
scan the input file
write to a second output file
delete the input
rename the output
As far as the dos commands to parse, I did a Google Search and came up with a good starting point:
#echo off
setlocal enabledelayedexpansion
set file=c:\file.txt
set output=output.txt
set maxlines=5000
set count=0
for /F "tokens=* usebackq" %%G in ("%file%") do (
if !count!==%maxlines% goto :eof
set line=%%G
set line=!line:*000000000000=--FOUND--!
if "!line:~0,9!"=="--FOUND--" (
echo %%G>>"%output%"
set /a count+=1
)
)
(Stolen from teh Intarwebnet)

Search and replace with a batch file

I am writing a batch file script using Windows command and want to change each occurrence of some blank space with "," What is the simplest way to do that?
If your users are a list of words on one line in a text file, separated by spaces, eg:
one two three four
Create a batch file SpaceToComma.bat as follows:
#echo off
setlocal
for /F "tokens=* delims= " %%a in (%1) do #set data=%%a
echo %data: =,%
endlocal
Then run it, you'll get the words separated by commas. Is this what you want?
C:\>SpaceToComma.bat data.txt
one,two,three,four
If you have a multi-line file, then this will do it:
data.txt
one two three four
five six seven
SpaceToComma.bat
#echo off
setlocal
for /F "tokens=* delims= " %%a in (%1) do #call :processaline %%a
endlocal
goto :eof
:processaline
setlocal
set data=%*
echo %data: =,%
endlocal
goto:eof
Output
C:\>SpaceToComma.bat data.txt
one,two,three,four
five,six,seven
(There's probably a clever way of doing this without the subroutine, using the !data! syntax for delayed variable expansion, but I couldn't get it to work with the substitution syntax.)
If this is not what you want, then please explain and I can try to help.
(PS: I delight in using batch files where people insist it can't be done.)
You could download sed.exe from http://unxutils.sourceforge.net/ and run this command:
sed -e "s/ /,/" infile.txt >outfile.txt
Well it will depend a lot on how you are getting the data, but you may be able to finagle something with a For-Do construct. Make the field seperator be a space then build the string back in the do with a , between each token. Might I suggest a more robust scripting language? You should have VBScript on just about any relatively modern windows bow.