How to remove the new line being printed in the .dat file - batch-file

I am doing an ftp batch script. It's an mget command but I have an error with the file name because it has ":"(colon)s in it. So my codes does a for loop which does the get command multiple times. My problem is, is that the .dat file has an empty line which is an error for the ftp command.
Below is my code:
#echo off& setlocal enableextensions
Echo open sample.net>second.dat
Echo user»second.dat
Echo pass»second.dat
Echo ascii»second.dat
Echo cd path/path/path»second.dat
setlocal enabledelayedexpansion
for /f "delims=" %%a in (file_list.txt) do (
set "remote=%%a"
echo get !remote:~0,-1! !remote::=.!»second.dat)
endlocal
Echo bye»second.dat
ftp -v -i -s:second.dat
del second.dat
pause
The file_list.txt is the list of file names that I need to rename using this code
setlocal enabledelayedexpansion
for /f "delims=" %%a in (file_list.txt) do (
set "remote=%%a"
echo get !remote:~0,-1! !remote::=.!»second.dat)
endlocal
The output file is this one
sample.net
user
pass
ascii
cd path/path/path
get logsample-txt-871749063-10-17-2017_22:00:05:692474.txt logsample-txt-871749063-10-17-2017_22.00.05.692474.txt
get logsample-txt-871749063-10-18-2017_08:00:57:671751.txt logsample-txt-871749063-10-18-2017_08.00.57.671751.txt
get logsample-txt-871749063-10-18-2017_08:00:07:724779.txt logsample-txt-871749063-10-18-2017_08.00.07.724779.txt
bye
What I what is, I need to remove the blank spaces for the ftp command to read it properly
sample.net
user
pass
ascii
cd path/path/path
get logsample-txt-871749063-10-17-2017_22:00:05:692474.txt logsample-txt-871749063-10-17-2017_22.00.05.692474.txt
get logsample-txt-871749063-10-18-2017_08:00:57:671751.txt logsample-txt-871749063-10-18-2017_08.00.57.671751.txt
get logsample-txt-871749063-10-18-2017_08:00:07:724779.txt logsample-txt-871749063-10-18-2017_08.00.07.724779.txt
bye

Related

How can I output each variable from a FOR loop to it's own file

I'm trying to run a query with a FOR loop and have each resulting variable line of the query output into it's own file.
I can't seem to get the delayed expansion variables to behave the way I want them to.
Basically I'm querying the printers installed on a print server and I want a .bat job containing certain text with the result output to multiple files containing the result name.
I think the problem is I'm not escaping some characters correctly, or I'm missing a % or ! on a variable, or some combination thereof.
#echo off
setlocal enabledelayedexpansion
FOR /F "tokens=1 delims=*" %%G IN ('wmic /node:PRINTSERVER printer get name') DO (
SET printer=%%G
SET printers=!printers: =!
SET printers=!printers:Name=!
ECHO ^(
#ECHO OFF
ECHO PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
ECHO.
ECHO ^"%windir%\system32\cscript %windir%\system32\prnmngr.vbs -ac -p \\PRINTSERVER\!printer!"^)>>!printer!.bat
)
endlocal
Expected results should be multiple files named PRINTERSHARENAME.bat
Each which contains:
#ECHO OFF
ECHO PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
ECHO.
%windir%\system32\cscript %windir%\system32\prnmngr.vbs -ac -p "\\PRINTSERVER\PRINTERSHARENAME"
EDIT
I will share more of my code. the wmic output contains spaces that had to be stripped, so this is why I used enabledelayedexpansion
EDIT2
Here is the output of my wmic command (Note that there are trailing spaces I've stripped out in the above code and the word 'Name' and a blank line at the end of the command):
C:\Users\bleepbloop>wmic /node:PRNTSVR printer get name
Name
PRINTER1
PRINTER2
OFFICEPRINTER
EDIT3
OK, I'm getting close. Here is code to reproduce, using an answer below:
(
echo Here is my first line
echo Here is my second line
echo Here is my third line
)>"textfile.txt"
FOR /F "delims=" %%G IN ('TYPE textfile.txt') DO (
(
ECHO #ECHO OFF
ECHO ECHO PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
ECHO ECHO.
ECHO "%%windir%%\system32\cscript" "%%windir%%\system32\prnmngr.vbs" -ac -p \\PRINTSERVER\%%G
)>%%G.bat
)
This works as expected and gives me 3 files named
Here is my first line.bat
Here is my second line.bat
Here is my third line.bat
however now I want to strip out all spaces from the variables output by textfile.txt, and for that I think I need to use delayed expansion?
So I want:
Hereismyfirstline.bat
Hereismysecondline.bat
Hereismythirdline.bat
I think I need to do this by using enabledelayedexpansion and inserting the following in the FOR loop:
SET variable=%%G
SET variable=!variable: =!
and then I have to insert the variable back into the loop properly. Still not sure how.
I want the file
Hereismyfirstline.bat
to contain
#ECHO OFF
ECHO PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
ECHO.
"%windir%\system32\cscript" "%windir%\system32\prnmngr.vbs" -ac -p \\PRINTSERVER\Hereismyfirstline
and the next file
Hereismysecondline.bat
to contain:
#ECHO OFF
ECHO PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
ECHO.
"%windir%\system32\cscript" "%windir%\system32\prnmngr.vbs" -ac -p \\PRINTSERVER\Hereismysecondline
I suggest this batch code for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "skip=1 eol=| tokens=*" %%I in ('%SystemRoot%\System32\wbem\wmic.exe /node:PRINTSERVER printer get name 2^>nul') do (
for /F "eol=| delims= " %%J in ("%%I") do (
set Printer=%%~nxJ
if defined Printer (
echo #echo off
echo echo PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
echo echo/
echo "%%SystemRoot%%\system32\cscript.exe" "%%SystemRoot%%\system32\prnmngr.vbs" -ac -p "\\PRINTSERVER\%%~nxJ"
)>"%%~nxJ.bat"
)
)
endlocal
Note: After delims= on second for command line must be a horizontal tab character and not one or more spaces as displayed by the web browsers according to HTML standard for the tab character.
Processing output of wmic is problematic because of this application outputs data always Unicode encoded using UTF-16 Little Endian encoding and for has a quirks on processing this Unicode output correct. For more details see for example How to correct variable overwriting misbehavior when parsing output?
The outer for processes the output of wmic with skipping first line containing heading Name. For all other non-empty lines all leading normal spaces and horizontal tabs are removed before assigning the rest of the line to specified loop variable I even on starting very unusual with a semicolon. | is not allowed in a printer name, but ; would be allowed although having never seen a printer name starting with ;.
The inner for with horizontal tab character as delimiter processes the printer name which can contain one or more spaces, but not a tab character. The printer name with all trailing horizontal tabs removed is assigned to specified loop variable J.
The remaining string is the printer name with trailing normal spaces. Windows prevents usually the creation of a file with trailing spaces. For that reason is assigned to environment variable Printer with using %%~nxJ just the printer name without trailing spaces. But spaces inside the printer name are kept by this command.
A single carriage return caused by the for quirks on processing of output of wmic results in getting environment variable Printer deleted instead of being defined with the carriage return.
So if the environment variable Printer is really defined with a printer name containing no, one or even more spaces, but no leading spaces/tabs and no trailing spaces/tabs, the batch file can be created with using printer name as assigned to loop variable J in batch file and in batch file name using %%~nxJ.
So there is no delayed environment variable expansion needed which makes this batch file working also for a printer name containing an exclamation mark.
See also DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ for the reason writing into the created batch files echo/ instead of echo..
This batch code uses delayed expansion inside the inner loop to remove all spaces from printer name for the batch file name.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "skip=1 eol=| tokens=*" %%I in ('%SystemRoot%\System32\wbem\wmic.exe /node:PRINTSERVER printer get name 2^>nul') do (
for /F "eol=| delims= " %%J in ("%%I") do (
set "Printer=%%~nxJ"
if defined Printer (
setlocal EnableDelayedExpansion
set "BatchFileName=!Printer: =!"
(
echo #echo off
echo echo PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
echo echo/
echo "%%SystemRoot%%\system32\cscript.exe" "%%SystemRoot%%\system32\prnmngr.vbs" -ac -p "\\PRINTSERVER\!Printer!"
)>"!BatchFileName!.bat"
endlocal
)
)
)
endlocal
It is absolutely no problem to run a batch file with one or more spaces in file name on enclosing entire batch file name in double quotes like any other file/folder name containing a space or one of these characters &()[]{}^=;!'+,`~. But this second batch file code demonstrates that it is possible to create the batch files with no spaces in file name while exclamation marks in printer name are nevertheless processed correct.
This code is slower than first code because of usage of setlocal and endlocal inside the loop. Read this answer for details about the commands setlocal and endlocal and what happens on every usage of these two commands in background making the second variant slower than the first variant.
Note: The printer name inside the batch file is with spaces. Just the batch file name is without spaces. But that can be easily changed if needed.
Parenthesis can group commands, but not split arguments. So, instead of ECHO (..., do:
SET printer=%%G
(
ECHO #ECHO OFF
ECHO ECHO PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
ECHO ECHO.
ECHO ^"%windir%\system32\cscript %windir%\system32\prnmngr.vbs -ac -p \\PRINTSERVER\!printer!"
)>!printer!.bat
Replaced >> with > which will create new files for each printer, instead of
appending more commands to existing files.
Noticed also you don't need delayed expansion, and probably "delims=" is more adequate.
Overall, your code may be rewritten as:
FOR /F "delims=" %%G IN ('wmic /node:PRINTSERVER printer get name') DO (
(
ECHO #ECHO OFF
ECHO ECHO PLEASE WAIT WHILE YOUR PRINTER IS INSTALLED
ECHO ECHO.
ECHO "%%windir%%\system32\cscript" "%%windir%%\system32\prnmngr.vbs" -ac -p \\PRINTSERVER\%%G
)>%%G.bat
)

delete command gets run before for loop

I am trying to setup a batch script which can connect to a set of servers and execute start script. Since there is a password getting saved in the commands.txt file. I need to delete it after the execution of start on remote servers. But that del command gets executed before everything and which is causing issues for the loop and errors out that commands.txt file is missing. Not sure how thats getting executed before the loop when its put after the loop. How can I fix this?
Below is the code I am trying.
#echo off
Echo Please enter your password in the popup window and then press enter
set tempbat="%temp%\p.cmd"
REM Create temporary batch file to make popup window for entering password 'masked'
echo mode 20,1 >%tempbat%
echo color EF >>%tempbat%
echo Title Enter Password >>%tempbat%
echo setlocal enabledelayedexpansion >>%tempbat%
echo set /p Pass= >>%tempbat%
echo echo !pass!^>"%temp%\pass.txt" >>%tempbat%
echo exit >>%tempbat%
echo exit >>%tempbat%
start /wait "" %tempbat%
set /p Password=<"%temp%\pass.txt"
#echo echo %password% ^| sudo -S -u x0ats echo startup.sh start>>
%cd%\commands.txt
#echo read>> %cd%\commands.txt
for /f "delims=" %%a in (%cd%\serverlist.txt) DO (
Start PuTTY username#%%a -pw %password% -m "%cd%\commands.txt"
)
del %cd%\commands.txt}
There are a few issues in your CMD script, but most specifically, as I mentioned above you are not putting double quotes around paths.
Additionally you were adding spaces to the ends of all of your line sin the bat file but that will cause you to collect the wrong PW, you also didn't delete your temp bat file or password file after the fact.
It seems like a bit of trouble to go through just to pop up a separate window, you could forgo creating a second batch file and call a sub function instead by making your script support cmd line arguments.
In Any case this should work more as you expect:
#ECHO OFF
ECHO.Please enter your password in the popup window and then press enter
SET "_TempBat=%temp%\p.cmd"
SET "_PWFile=%temp%\pass.txt"
SET "_CMDs=%cd%commands.txt"
REM Create temporary batch file to make popup window for entering password 'masked'
ECHO.SETLOCAL>"%_TempBat%"
REM ECHO.ECHO OFF >"%_TempBat%"
ECHO.mode CON COLS=42 LINES=1 >"%_TempBat%"
ECHO.color CF>>"%_TempBat%"
ECHO.Title Enter Password >>"%_TempBat%"
ECHO.SET /p "_Pass=Enter Password: " >>"%_TempBat%"
ECHO.ECHO.%%_pass%%^>"%_PWFile%">>"%_TempBat%"
ECHO.exit>>"%_TempBat%"
ECHO.exit>>"%_TempBat%"
START /wait "" "%_TempBat%"
DEL /F /Q "%_TempBat%"
IF NOT EXIST "%_PWFile%" (
"%_PWFile%" Not Created!
) ELSE (
FOR /F "Tokens=*" %%A IN ('TYPE "%_PWFile%"') DO (
SET "_PW=%%A"
DEL /F /Q "%_PWFile%"
)
)
#ECHO.ECHO.%_PW% ^| sudo -S -u x0ats ECHO.startup.sh start>> "%_CMDs%"
#ECHO.read>> "%_CMDs%"
for /f "delims=" %%a in ('Type "%_CMDs%"') DO (
Start PuTTY username#%%a -pw %_PW% -m "%_CMDs%"
)
Pause
DEL /F /Q "%_CMDs%"
ALSO I changed the colors you chose Bright Yellow on Bright right is hardly readable, I used Bright white on Bright Red. oh and I also added an Echo Off into your second script because again that was not helpful to have all the extra stuff in there
Also I looked at this and noticed that you were not going to get the PW saved in the PW file so I fixed that by using %% so that the first % will get stripped off.

Batch Finding and displaying duplicate strings in file names

I have a question. Is it possibile in batch language to search in folder a part of name that is same like another file and display it.For example i got folder with files :
ggggggsss.mp3
ddddddeee.mp3
ddddddff.mp3
ssssssddd.mp3
aaaaasssss.mp3
11111ssdas.mp3
11111dddd.mp3
...
I need to display in cmd only names of files
ddddddeee
ddddddff
and
11111ssdas
11111dddddd
Because the first six letter are the same. Could someone help me with this problem?
Save this script to test.bat and run from open Cmd Prompt. Replace dir value with path to your folder with .mp3 files:
#echo off
setlocal enabledelayedexpansion
set "dir=%userprofile%\music"
set "pattern1=dddddd" & set "pattern2=11111"
pushd "%dir%"
FOR %%G IN (*.mp3) DO ( set song=%%G
if "!song:~0,6!"=="%pattern1%" echo %%G)
echo/
FOR %%G IN (*.mp3) DO ( set song=%%G
if "!song:~0,5!"=="%pattern2%" echo %%G)
popd
exit /b
See also Extract Substrings.

Batch File That Copies a Line from a Text File and Stores it in a Variable

I have a batch file, which I will post below, I am trying to have it copy the first line in a file and then stores it in a variable.
#echo off
setlocal enabledelayedexpansion
set SEPARATOR=/
set filecontent=
for /f "delims=" %%a in ("MavenInstructions.txt") do (
set currentline=%%a
set filecontent=!filecontent!%SEPARATOR%!currentline!
)
echo The file contents are: %filecontent%
echo %filecontent%
pause
The first line of the MavenInstructions.txt is TEST LINE but what I get when I run my batch file is:
The file contents are: /MavenInstructions.txt
/MavenInstructions.txt
Press any key to continue . . .
for /f "usebackqdelims=" %%a in ("MavenInstructions.txt") do (
usebackq is required if the filename is "quoted".
btw - set filecontent=!filecontent!%SEPARATOR%%%a
would suffice.

redirecting .exe output within batch script to txt file

i am trying to redirect output from an exe(commanline exe) which is being called in from batch file to log file. In this script IP addresses of hostnames provided in input.txt are being redirected to result.txt. i am trying to run .exe within same batch script to place those IPs in maintenance mode in my monitoring tool. Script runs fine and performs the action as expected but it fails to capture the output from .exe. please help.
#echo off
setlocal enabledelayedexpansion
set OUTPUT_FILE=result.txt
>nul copy nul %OUTPUT_FILE%
for /f %%i in (input.txt) do (
set SERVER_ADDRESS=ADDRESS N/A
for /f "tokens=1,2,3" %%x in ('ping -n 1 %%i ^&^& echo SERVER_IS_UP') do (
if %%x==Pinging set SERVER_ADDRESS=%%y
if %%x==Reply set SERVER_ADDRESS=%%z
if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
)
echo !SERVER_ADDRESS::=!>>%OUTPUT_FILE%
)
start c:\MaintenanceMode.exe ON %OUTPUT_FILE% %USERNAME% >> "c:\result2.txt"
Output from .exe if i run it directly from command prompt:
PS C:\> .\MaintenanceMode.exe ON C:\result.txt username
Not an IP!!
Reading IPs from File: C:\result.txt
Valid Arguments
System put into MM Host# 10.*.*.* Status# Success
System put into MM Host# 10.*.*.* Status# Success
You are redirecting the output of the START command, but not the exe.
If you want to use START and redirect the output, then you most execute a new CMD.EXE session and escape the redirection so it occurs within the new session:
start cmd /c c:\MaintenanceMode.exe ON %OUTPUT_FILE% %USERNAME% ^>^> "c:\result2.txt"
But why are you using START? It would be so much simpler if you simply execute your exe directly:
c:\MaintenanceMode.exe ON %OUTPUT_FILE% %USERNAME% >> "c:\result2.txt"

Resources