index.txt:
2 6
8 12
text.txt number 1~15 are head number.
1
2
3 a
4 b
5 c
6
7
8
9 e
10 f
11 g
12
13
14
15
I want to print number 2~6 and 8~12 line
code:
setlocal EnableExtensions EnableDelayedExpansion
for /f "tokens=1,2,* delims= " %%a in (index.txt) do (
set /a start=%%a
set /a final=%%b
for /f "skip=%start% tokens=1,* delims=:" %%i in ('findstr /n ".*" text.txt') do (if %%i LEQ %final% echo %%j)
)
endlocal
but this not work
for /f "tokens=1,* delims=:" %%i in ('findstr /n ".*" text.txt') do (if %%i GEQ %%a if %%i LEQ %%b echo %%j)
No need to use start or final at all.
Related
I've pieced together a batch file based on info I've found here. Oddly, an earlier version appeared to work correctly at home, once I took it to work, it didn't. And all my modifications are failing to fix it. My boss and I are stuck.
#echo off
setlocal
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:"IPv4 Address"`) do (
for /f "tokens=1-4 delims=. " %%a in ("%%f") do (
set octetA=%%a set octetB=%%b set octetC=%%c set octetD=%%d
if %octetB% equ 10 goto :setschool
)
)
:setschool
if %octetC% geq 0 if %octetC% leq 3 set school=DIC
if %octetC% geq 16 if %octetC% leq 19 set school=AT
if %octetC% geq 48 if %octetC% leq 51 set school=BE
if %octetC% geq 64 if %octetC% leq 67 set school=BH
if %octetC% geq 80 if %octetC% leq 83 set school=CN
if %octetC% geq 112 if %octetC% leq 115 set school=LC
if %octetC% geq 128 if %octetC% leq 131 set school=LX
if %octetC% geq 144 if %octetC% leq 147 set school=RG
if %octetC% geq 160 if %octetC% leq 163 set school=UN
if %octetC% geq 176 if %octetC% leq 179 set school=WA
if %octetC% geq 192 if %octetC% leq 195 set school=WI
if %octetC% geq 208 if %octetC% leq 211 set school=BOE
echo %school%
goto :eof
It errors out at the first 'if', because octetB hasn't been set to anything yet. Yet the code just before it should have set it. All of our wired DHCP addresses start with 10.10., which is why it's checking for 10, which should mean it ignores our wireless, auto configed IPs, and virtual nics. If I manually run the lines before the 'if', it produces what I expect, with the octets being set correctly.
I suspect that the output of ipconfig is different at home and at work. Do you run the same operating systems on them? With the same language setting? Do the ipconfig outputs on both machines contain a IPv4 Address line when checked manually?
But I cannot tell anything without knowing the "earlier version that worked" you mentioned.
You can try using a simpler search String that is common on both machines, like IPv4. And maybe you want to add the /I switch to the findStr call to set it to "ignore case".
Try checking for equality with if "%%b" == "10" goto setschool (remove the colon, replace %octetB%). I think %octetB% is only available inside the for loop if you work with delayed expansion of variables.
You need to put each set command on its own line inside the for loop.
With these changes it works for me at least under Win10.
This is how I find which IP subnet our machines are using:
ipconfig^|findstr /i /c:"ip address"^|findstr /c:"10.11.1"&&set loc=AAA&&goto :continue
ipconfig^|findstr /i /c:"ipv4 address"^|findstr /c:"10.11.1"&&set loc=AAA&&goto ipconfig^|findstr /i /c:"ip address"^|findstr /c:"192.168.4."&&set loc=BBB&&goto :continue
:continue
ipconfig^|findstr /i /c:"ipv4 address"^|findstr /c:"192.168.4."&&set loc=BBB&&goto :continue
set loc=unknown
:continue
I think "ip address" is from WinXP or Win7.
You need delayed expansion.
untested
#echo off
setlocal enabledelayedexpansion
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:"IPv4 Address"`) do (
for /f "tokens=1-4 delims=. " %%a in ("%%f") do (
set octetA=%%a & set octetB=%%b & set octetC=%%c & set octetD=%%d
if "!octetB!" equ "10" goto :setschool
)
)
Here's a Remarked batch file example, showing the fix for your issues, as per my initial comment:
#Echo Off
Rem Undefine any existing octet variables.
For /F "Delims==" %%G In ('Set octet 2^>NUL') Do Set "%%G="
Rem Retrieve the IPv4 string from the IPConfig command.
Rem And set each octet to individual variables.
For /F "Tokens=2 Delims=:" %%G In (
'"%__AppDir__%ipconfig.exe 2>NUL | %__Appdir__%find.exe "IPv4""'
) Do For /F "Tokens=1-4 Delims=. " %%H In ("%%G"
) Do Set "octet1=%%H" & Set "octet2=%%I" & Set "octet3=%%J" & Set "octet4=%%K"
Rem Check to see if any octet variables are defined, i.e. IPv4 found.
Rem If not print message, wait for response and end the script.
Set octet >NUL 2>&1 || (Echo IPConfig failed to retrieve an IP address.
Pause & GoTo :EOF)
Rem From here you can make your comparisons:
Rem First ensure that a variable named school is not defined.
Set "school="
Rem Check to see if your second octet was 10.
Rem Then make your comparisons using the value of the third octet.
If %octet2% Equ 10 If Defined octet3 (
If %octet3% GEq 0 If %octet3% LEq 3 Set "school=DIC"
If %octet3% GEq 16 If %octet3% LEq 19 Set "school=AT"
If %octet3% GEq 48 If %octet3% LEq 51 Set "school=BE"
If %octet3% GEq 64 If %octet3% LEq 67 Set "school=BH"
If %octet3% GEq 80 If %octet3% LEq 83 Set "school=CN"
If %octet3% GEq 112 If %octet3% LEq 115 Set "school=LC"
If %octet3% GEq 128 If %octet3% LEq 131 Set "school=LX"
If %octet3% GEq 144 If %octet3% LEq 147 Set "school=RG"
If %octet3% GEq 160 If %octet3% LEq 163 Set "school=UN"
If %octet3% GEq 176 If %octet3% LEq 179 Set "school=WA"
If %octet3% GEq 192 If %octet3% LEq 195 Set "school=WI"
If %octet3% GEq 208 If %octet3% LEq 211 Set "school=BOE")
Rem As your comparisons do not currently cover all possible octet values,
Rem This is a check to see if the school variable was actually defined.
Rem If not print message, otherwise print the content of the school variable.
If Not Defined school (Echo The school variable was not defined.
Echo Reason: & If %octet2% Neq 10 (Echo The second octet was not 10.
) Else If Defined octet3 (Echo The third octet failed the comparisons.
) Else Echo Your returned IP address was corrupted.) Else Echo %school%
Rem Wait to ensure that any messages can be read, if not run from cmd.exe.
Pause
Rem End script.
GoTO :EOF
The script includes some additions designed to provide reasonable feedback if errors occur.
Feel free to use this unRemarked version for completion or in your production environment.
#Echo Off
For /F "Delims==" %%G In ('Set octet 2^>NUL')Do Set "%%G="
For /F "Tokens=2 Delims=:" %%G In (
'"%__AppDir__%ipconfig.exe 2>NUL|%__Appdir__%find.exe "IPv4""'
)Do For /F "Tokens=1-4Delims=. " %%H In ("%%G"
)Do Set "octet1=%%H"&Set "octet2=%%I"&Set "octet3=%%J"&Set "octet4=%%K"
Set octet>NUL 2>&1||(Echo IPConfig failed to retrieve an IP address.
Pause&GoTo :EOF)
Set "school="
If %octet2% Equ 10 If Defined octet3 (
If %octet3% GEq 0 If %octet3% LEq 3 Set "school=DIC"
If %octet3% GEq 16 If %octet3% LEq 19 Set "school=AT"
If %octet3% GEq 48 If %octet3% LEq 51 Set "school=BE"
If %octet3% GEq 64 If %octet3% LEq 67 Set "school=BH"
If %octet3% GEq 80 If %octet3% LEq 83 Set "school=CN"
If %octet3% GEq 112 If %octet3% LEq 115 Set "school=LC"
If %octet3% GEq 128 If %octet3% LEq 131 Set "school=LX"
If %octet3% GEq 144 If %octet3% LEq 147 Set "school=RG"
If %octet3% GEq 160 If %octet3% LEq 163 Set "school=UN"
If %octet3% GEq 176 If %octet3% LEq 179 Set "school=WA"
If %octet3% GEq 192 If %octet3% LEq 195 Set "school=WI"
If %octet3% GEq 208 If %octet3% LEq 211 Set "school=BOE")
If Not Defined school (Echo The school variable was not defined.
Echo Reason:&If %octet2% Neq 10 (Echo The second octet was not 10.
)Else If Defined octet3 (Echo The third octet failed the comparisons.
)Else Echo Your returned IP address was corrupted.)Else Echo %school%
Pause
GoTO :EOF
is there a way to make a If query for specifig
number sections in Batch?
Something Like this:
IF "Var1"=="1-10" (
do something
)
the 1-10 should stand for 1,2,3,4,5,6,7,8,9,10.
I want to make 10 queries (1-10,11-20,21-30, ... , 91-100)
Is that possible?
You can do this:
#echo off
set Var1=1
for /l %%i in (0,1,10) do if %%i==%Var1% echo 10 or below
for /l %%i in (11,1,20) do if %%i==%Var1% echo 11 - 20
for /l %%i in (21,1,30) do if %%i==%Var1% echo 21 - 30
for /l %%i in (31,1,40) do if %%i==%Var1% echo 31 - 40
for /l %%i in (41,1,50) do if %%i==%Var1% echo 41 - 50
for /l %%i in (51,1,60) do if %%i==%Var1% echo 51 - 60
for /l %%i in (61,1,70) do if %%i==%Var1% echo 61 - 70
for /l %%i in (71,1,80) do if %%i==%Var1% echo 71 - 80
for /l %%i in (81,1,90) do if %%i==%Var1% echo 81 - 90
for /l %%i in (91,1,100) do if %%i==%Var1% echo 91 - 100
Here you can change set Var1=1 to any other number and it will correspond. You can replace echo N - N with your commands.
Also, set Var1=1 can be removed from the above example if used with your code as I simply set it to demonstrate the behaviour. Here is an extract from the help when running for /? so you understand the numeric behaviour.
FOR /L %variable IN (start,step,end) DO command [command-parameters]
The set is a sequence of numbers from start to end, by step amount.
So (1,1,5) would generate the sequence 1 2 3 4 5 and (5,-1,1) would
generate the sequence (5 4 3 2 1)
I am new to Batch and I would like to know if I can find out all combinations of numbers in order.
In this case I have 49 Numbers from 1 - 49 , and I have to pick 6 Numbers to be the results.
For example:
1 2 3 4 5 6
1 2 3 4 5 7
...
1 2 3 4 5 49
1 2 3 4 6 7
1 2 3 4 6 8
etc...
This is my old code:
#echo off > NEWFILE & setLocal EnableDelayedExpansion
set a=44
set b=45
set c=46
set d=47
set e=48
set f=49
for /L %%a in (1 1 !a!) do (
for /L %%b in (2 1 !b!) do (
for /L %%c in (3 1 !c!) do (
for /L %%d in (4 1 !d!) do (
for /L %%e in (5 1 !e!) do (
for /L %%f in (6 1 !f!) do (
echo.%%a %%b %%c %%d %%e %%f
))))))) >> NEWFILE
goto :EOF
However it returns:
1 2 3 4 5 6
1 2 3 4 5 7
...
1 2 3 4 5 49
1 2 3 4 6 6
Two 6's appeared.
I don't seem to be able to fix it, please help, thanks very much!
When you post a question you should post your efforts to solve it, describe the method used and the problems you had; otherwise you may get similar answers with no explanations at all, like this one:
EDIT: As users dbenham and aschipfl indicated, my original code have a small bug: the set /A i=M-1 line should be placed after the :nextSet label. This is the right code:
#echo off
setlocal EnableDelayedExpansion
set "N=%1"
set "M=%2"
set "line="
for /L %%i in (1,1,%M%) do (
set "C[%%i]=%%i"
set "line=!line! ^!C[%%i]^!"
)
:nextSet
set /A i=M-1
for /L %%j in (!C[%M%]!,1,%N%) do (
set "C[%M%]=%%j"
echo %line%
)
:nextPos
set "C=!C[%i%]!"
if %C% equ %N% (
set /A i-=1
if !i! equ 0 goto :EOF
goto nextPos
)
for /L %%i in (%i%,1,%M%) do (
set /A C+=1,C[%%i]=C
)
if !C[%M%]! gtr %N% goto nextPos
goto nextSet
Obviously, the corrected code generate a much larger number of results and this version is particularly slow... :(
The new version below use the exact same code of dbenham's solution; its only advantage is that you may change the parameters used to generate the result in a very easy way:
#echo off
setlocal EnableDelayedExpansion
set "N=%1"
set "M=%2"
set /A j=N-M, prev=0
set "for=" & set "line=" & set "endfor="
for /L %%i in (1,1,%M%) do (
set /A j+=1
set "for=!for! set /A start=!prev!+1 & for /L %%%%i in (^!start^!,1,!j!) do ("
set "line=!line! %%%%i"
set "endfor=!endfor!)"
set "prev=%%%%i"
)
REM ECHO !FOR! echo !LINE! %ENDFOR%
%for% echo %line% %endfor%
Output example:
C:\> test.bat 6 4
1 2 3 4
1 2 3 5
1 2 3 6
1 2 4 5
1 2 4 6
1 2 5 6
1 3 4 5
1 3 4 6
1 3 5 6
1 4 5 6
2 3 4 5
2 3 4 6
2 3 5 6
2 4 5 6
3 4 5 6
To get your results, use: test.bat 49 6
2ND EDIT: Faster method added
When the problem to solve is the excessive time a process takes, an obvious alternative is to use a faster programming language. The solution below use JScript, that is somewhat similar to Batch file programming:
#if (#CodeSection == #Batch) #then
#echo off
echo Start: %time%
cscript //nologo //E:JScript "%~F0" > result.txt
echo End: %time%
goto :EOF
#end
// JScript code section
for ( var A=1; A <= 44; ++A ) {
for ( var B=A+1; B <= 45; ++B ) {
for ( var C=B+1; C <= 46; ++C ) {
for ( var D=C+1; D <= 47; ++D ) {
for ( var E=D+1; E <= 48; ++E ) {
for ( var F=E+1; F <= 49; ++F ) {
WScript.Echo(A,B,C,D,E,F);
}
}
}
}
}
}
This is a Batch-JScript hybrid script; save it with .BAT extension. This program took a little less than 9 minutes in my cheap-and-slow lap-top computer to generate a 239 MB file with 13983816 lines.
The problem is compute intensive, given that there are 13,983,816 unique permutations. (See https://en.wikipedia.org/wiki/Lottery_mathematics#Calculation_explained_in_choosing_6_from_49.)
The Rojo answer should work, but the GOTO and repetitive FOR /F parsing and IF logic will slow things down considerably.
The code is much faster if you use nested FOR /L loops.
#echo off
setlocal enableDelayedExpansion
for /l %%A in (1 1 44) do (
set /a start=%%A+1
for /l %%B in (!start! 1 45) do (
set /a start=%%B+1
for /l %%C in (!start! 1 46) do (
set /a start=%%C+1
for /l %%D in (!start! 1 47) do (
set /a start=%%D+1
for /l %%E in (!start! 1 48) do (
set /a start=%%E+1
for /l %%F in (!start! 1 49) do (
echo %%A %%B %%C %%D %%E %%F
)
)
)
)
)
)
This will still be unbearably slow to let this script print the results to the screen. I estimate it will take 1.25 hours on my machine. Redirecting the output to a file is about 5 times faster, around 15 minutes.
In the future, please show some code demonstrating that you've attempted to solve the problem yourself, showing where you got stuck, where the output is not as expected, etc. Questions resembling "Here are my requirements. Code this for me" generally aren't well-received around here. How you got an upvote without showing any code is beyond me, but c'est la vie.
In this instance, I found the problem interesting, so I thought I'd go ahead and get you started. Challenge: accepted. Here's one way to do it.
#echo off
setlocal enabledelayedexpansion
set "series=1 2 3 4 5 6"
:loop
echo %series%
if "%series%"=="44 45 46 47 48 49" goto :EOF
for /f "tokens=1-6" %%a in ("%series%") do (
set /a i1=%%a, i2=%%b, i3=%%c, i4=%%d, i5=%%e, i6=%%f+1
if !i6! gtr 49 set /a i5+=1, i6=i5+1
if !i5! gtr 48 set /a i4+=1, i5=i4+1, i6=i5+1
if !i4! gtr 47 set /a i3+=1, i4=i3+1, i5=i4+1, i6=i5+1
if !i3! gtr 46 set /a i2+=1, i3=i2+1, i4=i3+1, i5=i4+1, i6=i5+1
if !i2! gtr 45 set /a i1+=1, i2=i1+1, i3=i2+1, i4=i3+1, i5=i4+1, i6=i5+1
set "series=!i1! !i2! !i3! !i4! !i5! !i6!"
)
goto loop
Here's another solution that should be more efficient.
#echo off
setlocal enabledelayedexpansion
set "series=1 2 3 4 5 6"
set total=0
for /L %%a in (1,1,44) do (
set /a i2 = %%a + 1
for /L %%b in (!i2!, 1, 45) do (
set /a i3 = %%b + 1
for /L %%c in (!i3!, 1, 46) do (
set /a i4 = %%c + 1
for /L %%d in (!i4!, 1, 47) do (
set /a i5 = %%d + 1
for /L %%e in (!i5!, 1, 48) do (
set /a i6 = %%e + 1
for /L %%f in (!i6!, 1, 49) do (
rem // Uncomment this echo to watch the progress (severely decreases efficiency)
rem echo %%a %%b %%c %%d %%e %%f
set /a total += 1
)
)
)
)
)
echo Total so far: !total!
)
rem // Should have gone through 13983816 iterations
In a Windows cmd script (aka bat script), I have a FOR /L loop from 1 to 8, where I need to do a bit shift and somehow format a variable as a hexadecimal number (which if you ask, is a single CPU identifier bit to feed into /AFFINITY).
I can't figure out how to do the last step. This is my loop.cmd file:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /L %%i IN (1,1,8) DO (
SET /A "J=1<<%%i"
ECHO %%i and !J!
)
which does everything but format a hex number:
1 and 2
2 and 4
3 and 8
4 and 16
5 and 32
6 and 64
7 and 128
8 and 256
expected output is:
1 and 2
2 and 4
3 and 8
4 and 10
5 and 20
6 and 40
7 and 80
8 and 100
How do you format a hexadecimal number?
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /L %%i IN (1,1,8) DO (
SET /A "J=1<<%%i"
CALL :DECTOHEX J
ECHO %%i and !J!
)
GOTO :EOF
:DECTOHEX VAR
SET "DEC=!%1!"
SET "HEX="
:NEXT
SET /A DIGIT=DEC%%16, DEC/=16
SET "HEX=%DIGIT%%HEX%"
IF %DEC% NEQ 0 GOTO NEXT
SET "%1=%HEX%"
EXIT /B
EDIT: Reply to the comment
Previous solution works correctly when the shifted value have just one bit on, as stated in the question. If the shifted value may have several bits on then a more general decimal-to-hexadecimal conversion is required, like the one below:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM DEFINE THE HEXA DIGITS
SET "HEXA=0123456789ABCDEF"
FOR /L %%i IN (1,1,8) DO (
SET /A "J=3<<%%i"
CALL :DECTOHEX J
ECHO %%i and !J!
)
GOTO :EOF
:DECTOHEX VAR
SET "DEC=!%1!"
SET "HEX="
:NEXT
SET /A DIGIT=DEC%%16, DEC/=16
SET "HEX=!HEXA:~%DIGIT%,1!%HEX%"
IF %DEC% NEQ 0 GOTO NEXT
SET "%1=%HEX%"
EXIT /B
#echo off
setlocal enabledelayedexpansion
set x=2
set n=1
set /a result=n
for /l %%a in (1,1,10) do (
set /a result*=x
if "!result:~0,1!"=="1" set result=!result:16=10!
echo %%a and !result!
)
output:
1 and 2
2 and 4
3 and 8
4 and 10
5 and 20
6 and 40
7 and 80
8 and 100
9 and 200
10 and 400
#echo off
setlocal enableDelayedExpansion
set /a "counter=0"
set "cycle7zForw=273 256 192 128 96 64 48 32 24 16 12 8"
for /l %%N in (1 1 12) do (
set /a "counter+=1"
call :therest
)
set cycle
pause
exit
:therest
for /f "tokens=%counter%" %%i in ("%cycle7zForw%") do set cycle7zForw%%N=%%i
exit /b
How do I set a variable that counts the number of values inside cycle7zForw and then put it in for /l %%N in (1 1 %variable%) do (
On my example, it counts 12, but I don't want to manually write 12, because there could be any number of values inside cycle7zForw.
You could solve with a different approach.
This replaces the spaces into linefeeds.
Then a single FOR /F loops through all numbers.
#echo off
setlocal enableDelayedExpansion
set /a "counter=0"
set "cycle7zForw=273 256 192 128 96 64 48 32 24 16 12 8"
set temp=!cycle7zForw: =^
!
for /f "delims=" %%i in ("!temp!") do (
set /a counter+=1
set cycle!counter!=%%i
)
set cycle