String Variables not setting in For Loop - batch-file

I think I have a simple problem. I have a file where I'm trying to format the output into columns. I think I found a way to do it here but the string1 and string2 variables are not setting. Any ideas? I'm not familiar with Windows scripting and come from Linux where it's much easier.
Make this:
San Disk USB Drive, 10-12-2013
Superdrive Disk USB Drive, 10-11-2013
look like this:
San Disk USB Drive 10-12-2013
Superdrive Disk USB Drive 10-11-2013
Code I'm using to read the text file:
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ temp_sorted_usb_history.txt"`) do (
set "var=%%a"
SETLOCAL EnableDelayedExpansion
set "var=!var:*:=!"
echo(!var!
for /F "tokens=1,2 delims=," %%b in ("!var!") do (
echo %%b%%c
set string1=%%b
set string2=%%c
set string1="%string1% "
set string2="%string2% "
echo !string1:~-40! !string2:~-40!
)
ping -n 4 -w 1 127.0.0.1 >NUL
ENDLOCAL
)
The problem is that I can't get the string variables to set.

I don't understand why you are using findstr command. This is the way I would do that:
setlocal EnableDelayedExpansion
for /F "tokens=1,2 delims=," %%b in (temp_sorted_usb_history.txt) do (
echo %%b%%c
set "string1=%%b "
set "string2=%%c "
echo !string1:~0,40! !string2:~0,40!
)
ping -n 4 -w 1 127.0.0.1 >NUL

With setlocal enabledelayedexpansion
variables in parentheses are referred to as !variable! instead of %variable%
You have two strings that do not use !variable! notation, and they should.
You could however use this style of syntax where the quotes are not actually part of the variable, and eliminate the two other lines.
set "string1=%%b "
set "string2=%%c "
Another option might be to have the date first, and sorting by date would be simple.
#echo off
for /F "tokens=1,2 delims=," %%b in (temp_sorted_usb_history.txt) do (
echo %%c - %%b
)

Related

Batch file to collect UUID and Serial number

I have been using this batch file to collect the Serial number and UUID number and output to a CSV and now it no longer works.
#echo off
set outputfile="Y:\HP\UUDI.csv"
for /f "delims== tokens=2" %%i in ('wmic csproduct Get "UUID" /value') do SET CSPRODUCT=%%i
for /f "delims== tokens=2" %%i in ('wmic bios get serialnumber /value') do SET SERIAL=%%i
echo UUID,Serial,>>%outputfile%
echo %CSPRODUCT%,%SERIAL%,>>%outputfile%
If someone can look at this file and help me understand what went wrong I would appreciate it
I don't understand what did you mean by "No Longer Works" ? Please be more explicit when you ask a question !
here is a test and tell me if this works or not on your side and i will edit this aswer according to your response !
#echo off
set "outputfile=%~dp0UUDI.csv"
#for /f %%i in (
'wmic csproduct Get "UUID" /value ^& wmic bios get serialnumber /value'
) do (
#for /f %%j in ("%%i") do set "%%j" & echo "%%j"
)
echo UUID,SerialNumber>"%outputfile%"
echo %UUID%,%SERIALNumber%>>"%outputfile%"
If exist "%outputfile%" Start "" "%outputfile%" & Exit
The only reason I can see for your provided code to change its behavior, is that which was commented already by Mofi. That is, you've somehow caused the location of WMIC.exe to have been removed from the %Path% environment.
I have decided to provide an alternative method of achieving your goal using your chosen command utility WMIC.exe, and using its full path, to prevent such a reliance in future.
The WMIC command is traditionally one of the slower ones, so this method invokes it only once. All you should need to do is Echo your commands, currently on lines 12and 14, each separated as in line 13. If any of your commands requires to Get more than one property, you should separate those with caret escaped commas, e.g. Get Property1^,Property2. The results, (subject to line/environment length limitations), will then be saved to variables, %Title%, and %Record%, which can later be output to a file outside of the loop. Note: all commands should use /Value, or the more correct, /Format:List.
Example, (don't forget to adjust your output file path on line 4 as needed):
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "outputfile=Y:\HP\UUDI.csv"
Set "WMIC=%SystemRoot%\System32\wbem\WMIC.exe"
Set "FIND=%SystemRoot%\System32\find.exe"
Set "Title="
Set "Record="
For /F "Tokens=1,* Delims==" %%G In ('
(
Echo CSProduct Get UUID /Value
^&
Echo BIOS Get SerialNumber /Value
^)
^| %WMIC% ^| %FIND% "="
') Do (If Not Defined Title (Set "Title=%%G") Else (
SetLocal EnableDelayedExpansion
For /F "Tokens=*" %%I In ("!Title!") Do (EndLocal
Set "Title=%%I,%%G"))
If Not Defined Record (Set "Record=%%H") Else (
SetLocal EnableDelayedExpansion
For /F "Tokens=*" %%I In ("!Record!") Do (EndLocal
Set "Record=%%I,%%H")))
If Defined Title ( Echo %Title%
Echo %Record%) 1>"%outputfile%"

Using a batch script, how do I count files in a remote folder using a ip list/reference file and output it in a ip + filecount format?

What I want to achieve is have an output file that lists how many files are in a specific folder on a number of different remote machines ie(127.0.0.1 394files).
The issue I'm having is the output file generated only has 1 line in it, the last IP in ip.txt
To try and explain the code below, I'm creating a variable called 'testip' which should match the ip/machine I'm calling from ip.txt , this is created purely for the echo at the end, when I tried calling %%i or %%b at an echo, all that appears in the text file is %i or %b , as if its truncating 1 of the % characters. creating a separate variable (SET testip=%%b) got around that issue.
Next loop, it looks for the IP list in the ip.txt file and performs a count on the \test_scripts\ folder.
Then it should echo the IP it ran as well as the count number.
Any idea where this is going wrong?
Any feedback appreciated.
#ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "delims=" %%b in (' type "C:\Users\testuser\Desktop\test_scripts\ip.txt" ' ) DO SET testip=%%b
for /f "delims=" %%i in (' type "C:\Users\testuser\Desktop\test_scripts\ip.txt" ' ) DO (
SET count=0
for %%o IN ('type "\\%%i\c$\Users\testuser\Desktop\test_scripts\*.*" ' ) DO (
SET /A count=count + 1
)
)
echo %testip% %count% >> output.txt
ENDLOCAL ENABLEDELAYEDEXPANSION
ENDLOCAL
Try this one instead. Note how delayed expansion is used. For more on the commands, run them with /? switch on cmdline. for instance. for /?
Also you will see that command type is not used at all.
#echo off
setlocal enabledelayedexpansion
set "location=C:\Users\testuser\Desktop\test_scripts\ip.txt"
for /f "delims=" %%i in (%location%) DO (
set "remote=\\%%i\c$\Users\testuser\Desktop\test_scripts\*"
set count=0
for %%x in (!remote!) do set /a count+=1
echo !remote! !count! >> output.txt
)
This is the same method as Gerhards answer but with two modifications. I've set the remote variable at the start of the script instead of repeating that on each iteration of the loop; and I'm outputting the IP address, instead of the remote path, with the file count.
#Echo Off
SetLocal EnableDelayedExpansion
Set "location=%UserProfile%\Desktop\test_scripts\ip.txt"
Set "remote=\\%%A\C$\Users\testuser\Desktop\test_scripts"
( For /F "Usebackq Delims=" %%A In ("%location%") Do (Set "#=0"
For %%B In ("%remote%\*") Do Set /A #+=1
Echo %%A !#!))>"output.txt"
This is similar except that it uses the Dir command to retrieve the file count. The Dir command can take account of hidden and system files etc.
#Echo Off
SetLocal EnableDelayedExpansion
Set "location=%UserProfile%\Desktop\test_scripts\ip.txt"
Set "remote=\\%%A\C$\Users\testuser\Desktop\test_scripts"
( For /F "Usebackq Delims=" %%A In ("%location%") Do (Set "_=" & Set "#="
For /F %%B In ('Dir "%remote%" /A-D/D') Do Set "#=!_!" & Set "_=%%B"
Echo %%A !#!))>"output.txt"
You can easily modify your location and remote paths on lines 3 and 4, ensuring that the \\%%A\ section remains unaltered.
In have not tested either script, nor have I made any attempt at error trapping etc. I'll leave that to you, should it be required.

Batch File: Assign random line of text file as variable for later use

I'm trying to write a very simple batch file for personal use...It's complete except for one thing I'm stumped on. Hopefully this is an easy fix (I'm effectively illiterate when it comes to code).
Basically what I'm trying to do is have the script choose a random line from a text file, do this a couple times with a couple different text files, then I wish to assign the output from each text file to a variable so that I can easily use them in various combinations...then repeat the process.
Here is what I have right now...
#ECHO OFF
:START
SETLOCAL
SETLOCAL EnableDelayedExpansion EnableExtensions
SET "list1=list1.txt"
FOR /f %%a IN ('type "%list1%"^|find /c /v ""') DO SET /a numlines=%%a
SET /A list1random=(%RANDOM% %% %NumLines%)
IF "%list1random%"=="0" (SET "list1random=") ELSE (SET "list1random=skip=%list1random%")
FOR /F "usebackq tokens=* %list1random% delims=" %%A IN (`TYPE %list1%`) DO (
>> output.txt ECHO %%A
)
:Finish
ENDLOCAL
GOTO START`
This procures the random line, and spits it to a text file. All is well, next step, take that random result and assign it to a variable...
#ECHO OFF
:START
SETLOCAL
SETLOCAL EnableDelayedExpansion EnableExtensions
SET "list1=list1.txt"
FOR /f %%a IN ('type "%list1%"^|find /c /v ""') DO SET /a numlines=%%a
SET /A list1random=(%RANDOM% %% %NumLines%)
IF "%list1random%"=="0" (SET "list1random=") ELSE (SET "list1random=skip=%list1random%")
FOR /F "usebackq tokens=* %list1random% delims=" %%A IN (`TYPE %list1%`) DO (
SET output1=%%A
)
>> output.txt ECHO %output1%
:Finish
ENDLOCAL
GOTO START
Now the output ceases to be random...instead it is always the last line of the referenced text file.
EDIT: The site suggested another question that was similar to mine. However, that person was having trouble getting the script to choose a valid line. I get a valid line every time, and a random one too (when I check it via echo), but a non-random line when proceeding on, assigning the output to a variable. I don't understand because it seems like a post-facto derandomization. I.E. the difference between the two scripts has nothing to do with procuring the random result, only what to do with that result AFTER it has it, right?
I appreciate any help in advance, this is the last step before I know everything I need to finish this, I'm excited!
Sorry, you're right...anyways, I figured out a simple workaround, probably not the quickest in terms of processing time, but whatever. Basically allow the initial part of the script to spit out the random result to a text file (as seemed to work just fine) then reference the text file as a variable.
#ECHO OFF
:START
SET "list1=list1.txt"
FOR /f %%a IN ('type "%list1%"^|find /c /v ""') DO SET /a numlines=%%a
SET /A listchoice=(%RANDOM% %% %NumLines%)
IF "%listchoice%"=="0" (SET "listchoice=") ELSE (SET "listchoice=skip=%listchoice%")
FOR /F "usebackq tokens=* %listchoice% delims=" %%A IN (`TYPE %list1%`) DO (
>> listoutput.txt ECHO %%A
)
Set /p list=<listoutput.txt
>> result.txt ECHO %list%
:Finish
DEL listoutput.txt
GOTO START
This is easy to do in PowerShell using the built-in Get-Random cmdlet.
$line = (Get-Content file.txt | where { $_ } | Get-Random)
Which makes it also easy in batch.
set filename=file.txt
for /f "tokens=*" %%a in ('powershell -ex bypass -c "gc %filename% | ? { $_ } | Get-Random"') do (
set "var=%%a"
)
The where { $_ } clause is only necessary to filter out any blank lines. You can omit it if you know your file has none.

Batch File: ' delims= " was unexpected at this time'

I've been trying to make a batch file that makes folders named after the people on a .txt file list, and then gives them full access to modifying their own personal folder.
The problem is that I keep getting a ' delims= " was unexpected at this time' error.
Here's my code here, I was wondering if you guys would be able to find out what I did wrong, thanks ^-^
(Btw I haven't added the permissions part yet, I just need to get this part sorted out first)
CODE: http://pastebin.com/XLi11nZa
NAMES LIST: http://pastebin.com/xbh3WTSv
#echo off
color A
echo What is the name of list file? (Do not include format)
SET /P list=
setlocal EnableDelayedExpansion
set "cmd=findstr /R /N "^^" %list%.txt | find /C ":""
for /f %%a in ('!cmd!') do set m=%%a
SET c=0
echo !m! folders to be created. Continue? (Y/N)
SET /P ANSWER=
if /i {%ANSWER%}=={y} (goto :yes)
if /i {%ANSWER%}=={yes} (goto :yes)
exit
:yes
echo Now creating %m% folders.....
for /f "eol=; tokens=1 delims=," %%i in ("%list%.txt") do (
SET /a c = !c! + 1
mkdir "%%i"
echo !c!/%m% folders created [%%i]
)
endlocal
echo Now adding permissions to %m% folders.....
pause
setlocal enabledelayedexpansion
SET c1=0
for /f "eol=; tokens=1 delims=," %%i in ("%list%.txt") do (
SET /a c1 = !c1! + 1
SET word=1
SET /a showme=c1-1
SET showme=skip=%showme%
IF !c1! equ 1 set "showme= "
FOR /F "tokens=%word% %showme% delims= " %%F IN ("%list%") DO if defined
showme set showme=%%F
SET first=%showme:~0,1%
SET word=2
SET /a showme1=c1-1
SET showme1=skip=%showme1%
IF %c1% equ 1 set "showme1= "
FOR /F "tokens=%word% %showme1% delims= " %%L IN ("%list%") DO if
defined showme1 set showme1=%%L
set B=%showme1%%first%
set _STRING=%B%
set "_UCASE=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set "_LCASE=abcdefghijklmnopqrstuvwxyz"
for /l %%a in (0,1,25) do (
call set "_FROM=%%_UCASE:~%%a,1%%
call set "_TO=%%_LCASE:~%%a,1%%
call set "_STRING=%%_STRING:!_FROM!=!_TO!%%
)
set _STRING
echo %_STRING%
echo %_STRING%>>testing.txt
endlocal
pause
)
names list
Loralee Stucky
Tomas Silberman
Marleen Rosell
Phyllis Steier
Elmo Jetter
Kristyn Spruell
Willetta Vandermeer
Hazel Alsobrook
Naida Nixon
Nadia Godfrey
Lavonna Antunez
Mac Castile
Tamela Stover
Piedad Heidrick
Hien Welsh
Carolin Gularte
Mariko Tolentino
Alia Graddy
Deadra Rehkop
Donella Pittman
Replace
for /f "eol=; tokens=1 delims=," %%i in ("%list%.txt") do (
by
for /f "usebackq eol=; tokens=1 delims=," %%i in ("%list%.txt") do (
twice.
Without the usebackq option, a double-quoted set of for /F is interpreted as a literal string rather than a file. Removing the double-quotes could work but could also lead to problems with files that have spaces in their names.
Another thing: you are dynamically creating the skip=# option for for /F, where # stands for a number. you have to make sure that this number is always positive, so 0 is not understood by for /F which could also lead to your error message.
So you could add an if check whether the number is greater than zero and do not add the skip option otherwise (by clearing your showme variables).
And last but not least: the delayed expansion is not always used properly: sometimes in the block startung at the for command in line #26 of your code and reaching to the end, you are not consistently using !! for expansion of variables showme, showme1 and c1, which are the ones that are modified within that code block.
The folders will get created proper if you remove the double quotes from the filename variable for /f "eol=; tokens=1 delims=," %%i in (%list%.txt) do ( change that line and you'll get past this part.
You may want to do the same in the permissions section.

Reading a specific column from a row using a batch file

I have a notepad which looks like this.
Job Name Last Start Last End ST Run/Ntry Pri/Xit
________________________________________________________________ ____________________ ____________________ __ ________ _______
DEV_xxx_xxx_xxx_xxxx_b 11/20/2012 22:05:00 ----- RU 9229277/1
This value "22:05:00" is present on the 77th column of row 3. Is there a way using a batch script that i can extract only this value and assign it to a variable. The above notepad is the redicrected output of an autosys command (if it helps)
I've been breaking my head for the past 3 days but to no avail.
Untested
#echo off
for /f "skip=2 delims=" %%a in (file.txt) do set "var=%%a"&goto :done
:done
set "var=%var:~76,8%"
echo "%var%"
pause
Another way (faster) to read the 3rd line.
#echo off
<file.txt (
set/p=
set/p=
set /p var=
)
set "var=%var:~76,8%"
Use a FOR /L loop if you want to skip a larger number of lines
#echo off
<file.txt (
for /l %%N in (1 1 2) do set/p=
set /p var=
)
set "var=%var:~76,8%"
If the job name never contains spaces, then it looks like you could also use FOR /F in the traditional way.
#echo off
for /f "skip=2 tokens=3" %%A in (file.txt) do set "var=%%A" & goto :break
:break
search it with GNU sed (very fast!)
for /f %%i in ('sed -n "/DEV/ {s/.*\([0-2][0-4]:[0-5][0-9]:[0-5][0-9]\).*/\1/p;q}" file.txt') do set "var=%%i"
echo %var%

Resources