I have batch script which read and executes command defined in command.txt on all the servers which ever mentioned in server.txt file using for loop.
problem is,am trying to get output/result file as "server_command.log" for each command executed.
I can easily get the server details but for commands, I need to get the last word from the command.txt file since each command has special character ie, /
command.txt content :
show /system1/firmware1
show /system1/fan1
server.txt will have ip address of target server :
10.1.1.101
10.1.1.103
10.1.1.105
output file am trying to get should be :
101.1.1.101_firmware1.log (file will contain fireware1 command output)
101.1.1.101_fan1.log (file will contain fan1 command output)
101.1.1.103_firmware1.log (file will contain fireware1 command output)
101.1.1.103_fan1.log (file will contain fan1 command output)
101.1.1.105_firmware1.log (file will contain fireware1 command output)
101.1.1.105_fan1.log (file will contain fan1 command output)
my batch file:
for /f "tokens=1" %%a in (.\config\serverlist.txt) do (
echo _
echo ----- Opening connection to: %%a at %TIME% ----- >> %LOGFILE%
for /f "tokens=*" %%c in (.\config\commands.txt) do (
set MyCmd=%%c
set Server=%%a
echo --------- %%c and %%a ------------------
set MyLog=.\Logs\!Server!_%MyDate%.!MyCmd!.log
.\plink -ssh %username%#!Server! -pw %password% "!MyCmd!" >> !MyLog!
)
echo. >> %LOGFILE%
echo ----- Closing connection to: %%a at !TIME! ----- >> %LOGFILE%
)
Thanks
replace your special symbol (/) with a space and use a simple for to get the last element:
...
set MyCmd=%%c
for %%X in (!MyCmd:/^= !) do set MyCmd=%%X
echo !MyCmd!
...
Related
I want to add few lines in a text file based on os name. A pseudocode example:
os==windows 7 then open file c:\1.txt else open file c:\2.txt
I want to add some static text to that text file and save the text file.
How do I do that in batch script? My pseudocode attempt:
FOR /F "delims=" %i IN ('ver') DO set osver=%i
echo %osver%
if %osver% == "Microsoft Windows [Version 6.1.7601]"
set filepath == C:\1.txt and open 1.txt file and add text" abc "
else
set filepath == C:\2.txt and open 2.txt file and add text " abc"
Do not over complicate it by creating variables, else you might need delayedexpansion
#echo off
for /f "tokens=2 delims=[]" %%i in ('ver ^| more +1') do (
if "%%i"=="Version 10.0.17134.228" echo abc >> "C:\1.txt"
if "%%i"=="Version 6.1.7601" echo abc >> "C:\2.txt"
)
We split away version X.X.X.X only as we want to match as little as possible. Then simply do if and echo to the relevant file.
For more on the above commands, see from cmdline for /? and if /?
You need to copy the above code into a text file and save it as a file with a .cmd or .bat extension. Please do not call it ver.bat or ver.cmd as ver is a system command. Call it something like my_version_script.cmd instead.
On Windows 10 I have this .bat:
#echo off
for /f "delims=" %%i in (filelist.txt) do (
echo %%~nxi >> output.txt
type "%%~ni*" >> output.txt
echo. >> output.txt
echo. >> output.txt
)
Exit
Now what this does is:
reads filelist.txt, which contains names of .txt files like:
20180808173105 (without ".txt"
searches for those files: 20180808173105.txt
copies name of files (without ".txt") into output.txt
inserts content of files
inserts two blank lines
repeats whole process for all files named in filelist.txt
--> It works fine! (or do you see any exception where this might malfunction?)
This inserts the full contents of a text file according to a list.
Can I modify it, so
not the whole content of a .txt, but only a part of it is inserted?
For example, everything from just after "title:" to just before "<!--"
if the filelist had a hierarchical structure (outline), it could
be preserved, like so:
#201508081213
###201609101219
to
#201508081213
TEXT
###201609101219
TEXT
I am using this to convert Outlines (using only the file names) to a rough first draft of text for writing articles and blogs
#echo off
2> output.txt echo.
#>&3 (
echo Debug Information
echo -----------------
)
for /f "delims=" %%A in (filelist.txt) do (
for %%B in ("%%~nA*") do call :read "%%~B"
) >> output.txt
exit /b
:read
setlocal
set "line="
echo(%~nx1
for /f "usebackq delims=" %%C in ("%~1") do (
set "line=%%C"
for /f "tokens=*" %%D in ('call echo "%%line:~0,4%%"') do (
#>&3 echo File: "%~1" Test: %%D == "<!--"
if %%D == "<!--" (
#>&3 echo Found: "<!--"
echo.
echo.
exit /b 0
)
)
call echo(%%line%%
)
echo.
echo.
exit /b 0
Note
Not the best language for this task. Had to avoid
enabledelayedexpansion as to known use of ! in <!--.
Used call even though < and some other characters
could cause issue.
for /f loops do not normally process empty lines so
hope that is not a problem.
Hierarchical structure depends on the order in filelist.txt.
The structure of a document can vary and I cannot consider
what the correct order might be. The use of a wildcard gives
some doubt. A filename #a will find #a1 and #a2 so
placement of 3 headings is unknown.
I have left in the std stream 3 messages for your
understanding of operation with the <!-- test.
Std stream 1 is the output that goes to file.
Operation
The file output.txt is erased before echoing text to the file.
The 1st for loop reads each line of the filelist.txt file.
The nested for loop gets the filenames with a wildcard.
Each call to label :read passes the argument of a filename.
In the label of :read, the filename is echoed.
A for loop reads lines from the filename.
Each line is stored in variable named line.
The nested for loop will use call echo to expand
the variable line and echoes the 1st 4 characters.
A comparison is done to test if it is <!-- and if so,
echo 2 newlines and then the label is exited.
If not, echo each line. echo 2 newlines is done at
the end of the label before exiting.
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
So I know how to save strings to a text file as a list from batch by using
set /p Myvar1="Enter your variable name/value: "
set /p Myvar2="Enter your variable name/value: "
set /p Myvar3="Enter your variable name/value: "
And then append to a text file
echo %Myvar1% %Myvar2% %Myvar3% >> Mylist.txt
So when I open the text file through the batch file, it can be displayed
as a list:
SET "variables="
ECHO =================================================
ECHO My list of stuff
ECHO =================================================
< Mylist.txt (
set /p MyVar1=
set /p MyVar2=
set /p MyVar3=
)
::set line
ECHO - [0] - %Myvar1%
ECHO - [1] - %Myvar1%
ECHO - [2] - %Myvar1%
Now the problem is that:
For each new line on the Mylist.txt text file I have to manually add lines on the batch file. On the provided example the batch is setup so it displays 3 lines of text from the text file. If the text file has 10 lines, it will only show the first 3 lines because that is what is specified. So I would like to accomplish the opposite of this script.
The batch file should be able to:
Batch file reads Mylist.txt.
For each line in Mylist.txt file the batch file creates a "numerated variable".
Each "numerated variable" can be addressable so the user can be prompted to select one of the options on the list 1, 2, 3, 4, etc.
The easiest method to save variable names and their values to a file is redirecting the output of command SET to a file.
set My >"%APPDATA%\MyVariables.txt"
This simple line saves all environment variables starting with My in name with name and value into file MyVariables.txt in application data directory of current user.
And following command line can be used in a batch file to reload those environment variables from file:
for /F "usebackq delims=" %%I in ("%APPDATA%\MyVariables.txt") do set "%%I"
Same command line for usage directly in a command prompt window:
for /F "usebackq delims=" %I in ("%APPDATA%\MyVariables.txt") do set "%I"
A little bit more secure would be checking if each line in the file MyVariables.txt really starts with My as expected and so was not manipulated by someone who wants to override for example PATH by adding manually to file MyVariables.txt a line starting with PATH=.
It might be useful to know how many variables were loaded from file. This can be achieved with a simple extension:
set "VariablesCount=0"
for /F "usebackq delims=" %%I in ("%APPDATA%\MyVariables.txt") do set "%%I" & set /A VariablesCount+=1
Of course if there is an environment variable MyVariablesCount starting with My then this variable with its value would be also saved into the file and reloaded from file which would make it unnecessary to count the number of variables set from file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
for /?
set /?
Read also the Microsoft article about Using Command Redirection Operators.
simple thing with a for loop plus a counter:
setlocal enabledelayedexpansion
set i=0
for /f "delims=" %%a in (mylist.txt) do (
set /a i+=1
set var[!i!]=%%a
)
echo number of variables: %i%:
set var[
echo ---------
for /l %%a in (1,1,%i%) do echo variable %%a = %var[%%a]%
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"