I have a phrase that needs to be outputted in results.txt. The phrase comes from x.txt. For example: "I have two kids", it should output "kids two have I" in results.txt.
UPDATE
Its already working but i want no loop.
Pls see code below
Code
#ECHO OFF
set /p content=<x.txt
SET var=!content: =,!
SET rev=
:LOOP
IF NOT "!var!"=="" (
FOR /F "delims=, tokens=1,*" %%F IN ("!var!") DO (
SET rev=%%F,!rev!
SET var=%%G
)
) ELSE (
SET rev=!rev:~0,-1!
GOTO ENDLOOP
)
GOTO LOOP
:ENDLOOP
ECHO !rev:,= ! > results.txt
This takes the first four words (of each line) of the text file and rewrites them in reverse order to result.txt:
>result.txt (for /f "tokens=1-4" %%a in (x.txt) do echo %%d %%c %%b %%a)
Another solution (for a one-line text file, unspecified number of words):
#ECHO OFF
setlocal enabledelayedexpansion
echo I have two little but wonderful kids>x.txt
<x.txt set /p x=
for %%a in (%x%) do set "res=%%a !res!"
>result.txt echo %res:~0,-1%
(although technically, the for command is a loop on its own)
Without any form of a loop, if you can live with some spaces at the front:
#ECHO OFF
setlocal
echo I have two kids>x.txt
<x.txt set /p x=
call :reverse %x%
goto :eof
:reverse
set "rev=%9 %8 %7 %6 %5 %4 %3 %2 %1"
echo Reverse without any form of loop: "%rev%"
for /f "tokens=*" %%a in ("%rev%") do echo To get rid of the spaces, you need a FOR loop: "%%a"
This is limited to a maximum of nine words because cmd supports only %1to %9
You can use more parameters (words) by using the shift command, but that would mean using a loop.
Here are three different ways.
Replacement magic (borrowed from Aacini)
For tokens
Recursion
#echo off
setlocal EnableDelayedExpansion
set "var=One two three four five"
call :rev1
call :rev2
call :rev3
exit /b
:rev1 -- replacement magic
setlocal
set "rev="
set rev=%var: = !rev!&Set rev=% !rev!
echo %0 !rev!
exit /b
:rev2 -- FOR toekns
setlocal
FOR /F "tokens=1-5" %%1 in ("%var%") do set "rev=%%5 %%4 %%3 %%2 %%1"
echo %0 !rev!
exit /b
:rev3 -- recursion
setlocal
set "rev="
call :__rev3_rec %var%
echo %0 !rev!
exit /b
:__rev3_rec
if "%1" == "" exit /b
call :__rev3_rec %2 %3 %4 %5
set "rev=%rev%%1 "
exit /b
I'm not sure if I've understood your question fully, so this is intended to reverse the order of each space separated substring per line.
For the task, I'd leverage PowerShell.
At the powershell prompt, (powershell.exe):
GC '.\x.txt'|%{$L=$_.Split(' ');[Array]::Reverse($L);$L -Join ' '}|SC '.\results.txt'
At the command-prompt, (cmd.exe):
"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "GC '.\x.txt'|%{$L=$_.Split(' ');[Array]::Reverse($L);$L -Join ' '}|SC '.\results.txt'
From a batch-file:
#"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "GC '.\x.txt'|%%{$L=$_.Split(' ');[Array]::Reverse($L);$L -Join ' '}|SC '.\results.txt'
If you're only working on the first line of the file, as opposed to all of them, a small modification is needed.
At the powershell prompt, (powershell.exe):
GC '.\x.txt' -To 1|%{$L=$_.Split(' ');[Array]::Reverse($L);$L -Join ' '}|SC '.\results.txt'
At the command-prompt, (cmd.exe):
"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "GC '.\x.txt' -To 1|%{$L=$_.Split(' ');[Array]::Reverse($L);$L -Join ' '}|SC '.\results.txt'
From a batch-file:
#"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "GC '.\x.txt' -To 1|%%{$L=$_.Split(' ');[Array]::Reverse($L);$L -Join ' '}|SC '.\results.txt'
Please note that, in both cases, if your strings are actually doublequoted, those will not move position. This means that "I have two kids", would output as kids" two have "I, not "kids two have I".
Related
I have text documents filled with URLs and when I count the number of lines inside the file, as soon as the line count is greater than 1000, I want to delete the lines which follow those, keeping the first 1000 lines.
This is my code but I can't figure out what I am doing wrong.
Create a text.txt file with this script location and put over 1000 lines of junk into it to test.
#ECHO OFF & setLocal EnableDelayedExpansion
color 0A
%*
SET root_path=%~dp0
set text_name=text.txt
set text_name_output=output_text.txt
set max_line_count=1000
set /a counter=0
for /f %%a in (%root_path%%text_name%) do (
set /a counter += 1
echo Number of lines: !counter!
if !counter! LSS %max_line_count% (
echo less than
) else (
echo more than so delete these line numbers
(for /f "tokens=1,* delims=[]" %%a in ('type %root_path%%text_name%^|find /v /n ""') do (
echo/%%a|findstr /x "!counter!" >nul || echo/%%b
))>%root_path%%text_name_output%
)
)
pause
Using a batch file for this task is absolutely not appropriate, however, here's a basic structure which should do what you asked, however slow that may be.
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "InFile=text.txt"
Set "LineLimit=1000"
Set "OutFile=output_text.txt"
If Not Exist "%InFile%" Exit /B
(
For /F Delims^= %%G In (
'%SystemRoot%\System32\findstr.exe /N /R "^" "%InFile%" 2^>NUL'
) Do (
Set "}=%%G"
Set /A "{=%%G" 2>NUL
SetLocal EnableDelayedExpansion
If !{! Gtr %LineLimit% (
EndLocal
GoTo Next
)
Echo(!}:*:=!
EndLocal
)
) 1>"%OutFile%"
:Next
I figured it out if the text or document has more than 1000 lines then delete all lines that follow.
#ECHO OFF & setLocal EnableDelayedExpansion
color 0A
%*
SET root_path=%~dp0
set text_name=text.txt
set text_name_output=output_text.txt
set max_line_count=1000
set /a counter=0
for /f %%a in (%root_path%%text_name%) do set /a counter+=1
set /a "counter=%counter%-%max_line_count%"
more +%counter% "%root_path%%text_name%" >"%root_path%%text_name_output%"
move /y "%root_path%%text_name_output%" "%root_path%%text_name%" >nul
pause
It sounds like you want a head program. This is easily done in PowerShell.
Get-Content -Path '.\text.txt' -First 1000 >'.\output_text.txt'
If you must run from cmd.exe, the following might be used.
powershell -NoLogo -NoProfile -Command ^
"Get-Content -Path '.\text.txt' -First 1000 >'.\output_text.txt'"
I want to know error line number where error was occure by batch script and also i want to print whole line in batch script?
set t=%date%_%time%
set x=FORD_DLCM_T6_FTC
set a="%m%\%x%"
cd /d "C:\PRQA\PRQA-Framework-2.1.2\common\bin"
qacli admin --set-license-server 5055#00.00.0.0 || goto :error
qacli admin --debug-level DEBUG || goto :error
goto :EOF
:error
set remark= %ERRORLEVEL%
set status= Failure
echo ProjectName: %x%
echo Status: %status%
echo Remark: %remark%
echo Date: %t%
echo %x%,%status%,traceback(),%t% > "C:\Test\Build.csv"
echo Failed with error #%errorlevel%.
exit /b %errorlevel%
can any one help me out?
jeb has described how the search for the right line works. in the event of an error, a call is triggered and the parameters are a unique string and an offset, which points to the number of missing lines to the correct line. Findstr looks for the unmistakable string and prints that line number. With the settlement that's right again.
I've put together some macros to show that there are other ways to read the right line.
#echo off
setlocal
set prompt=$g$s
call :setAllmacros
(call)
rem begin in echo off - what line is it please ?
%ID-1:##==rem?%
(call )
%ID-1:##==call%
set/a+
%ID-1:##==001% call :ErrorLogging Line:%%L Errorlevel:%errorlevel%
echo 2
(call) || %ID-0:##==2% call :Errorlogging Line:%%L Errorlevel:%%errorlevel%%
echo %errorlevel%
find /n || %ID-0:##==003% call :Errorlogging Line:%%L Errorlevel:%%errorlevel%%
%ID-0:##==008%
pushG 556
%ID-1:##==004% call :ErrorLogging Line:%%L Errorlevel:%errorlevel%
%Line#print%:33=="
pause
exit /b
:errorlogging
#echo on
rem %*
#echo off
exit /b
:setAllmacros
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
(set ^"lf=^
%== define LF + CR ==%
)
for /f %%i in ('copy /z "%~f0" nul') do set "CR=%%i"
rem Prints the fullline itself with LineNumber into stderr
rem usage: %Line#print%:UniqueID"
rem command || %Line#print%:01"
set "Line#print= # <"%~f0" >&2 find /n "%%Line#print%%"
rem Read the fullline BEFORE into Variables with LineNumber; do something ...
rem usage: command 1 line before
rem %ID-1:##==01% [command %%L ... %%M ...]
set ID-1= if errorlevel 1 for /f "usebackQtokens=1*delims=:" %%L in (^
`cmd /v /c ^"findstr /n /r /c:"..*^!CR^!*^!LF^!.*ID-1:.#^=^##%%" "%~f0"^"`) do ^>^&2 echo BatchLine: %%L -- %%M ^&
rem Read the fullline itself into Variables with LineNumber; do something ...
rem usage: command || %ID-0:##==01% [command %%L ... %%M ...]
set ID-0= # for /f "tokens=1*delims=:" %%L in ('findstr /n /r /c:"ID-0:.#=##%%" "%~f0"') do ^>^&2 echo BatchLine: %%L -- %%M ^&
exit /b
hope it helps
Phil
I have a text, for example:
cd123aaq54
and I'd like to separate only numbers in another file, so I could have
12354
in the output.
I have been trying a lot of commands like
Get-Content text.txt | Select-String -Pattern '[0-9]'
In linux it's much easier, just
grep -o '[0-9][0-9]*' text >numbers
I know that in Powershell is
#(Get-Content text.txt) -replace '\D',''
But it is too slow (I want it in a loop)
How can I do in in classic cmd?
Thanks!
#ECHO OFF
SETLOCAL
SET "input=cd123aaq54"
CALL :numsonly result "%input%"
ECHO %input% --^> %result%
SET "input=cd5z43a q21p"
CALL :numsonly result "%input%"
ECHO %input% --^> %result%
GOTO :EOF
:numsonly
setlocal
SET "$1="
SET "$2=%~2"
:numsloop
IF "%$2:~0,1%" geq "0" IF "%$2:~0,1%" leq "9" SET "$1=%$1%%$2:~0,1%"
SET "$2=%$2:~1%"
IF DEFINED $2 GOTO numsloop
endlocal&SET "%1=%$1%"
GOTO :eof
The :numsonly subroutine could be put into a separate batch file if desired.
I have this single line CMD file TEST.CMD:
for %%f in (%1 %2 %3 %4 %5 %6 %7 %8) DO ECHO %%f
If I run this:
TEST this is a test
it correctly echos each parameter on a separate line, i.e.,
this
is
a
test
However if a parameter contains asterisk it skips it. E.g.,
TEST this is a* test
Results in:
this
is
test
How do I get the parameter with an asterisk to be treated like a normal token?
Thanks.
The simplest method that works for most parameters is to transfer the parameters to an "array" of variables, and then use FOR /L to loop through the array. This is best achieved with delayed expansion.
This technique can process an arbitrary number of parameters - it is not limited to 9.
#echo off
setlocal
:: Transfer parameters to an "array"
set arg.cnt=1
:getArgs
(set arg.%arg.cnt%=%1)
if defined arg.%arg.cnt% (
set /a arg.cnt+=1
shift /1
goto :getArgs
)
set /a arg.cnt-=1
:: Process the "array"
setlocal enableDelayedExpansion
for /l %%N in (1 1 %arg.cnt%) do echo arg %%N = !arg.%%N!
The only way I have found without knowing the parameters beforehand is to echo the parameters in the for loop
for /f %%f in ('"echo %1 && echo %2 && echo %3 && etc"') DO ECHO %%f
You can't print that, the asterisk is a dynamic operator that matches "1 or more characters" in some commands, like the FOR command, the only way is to use the /F parameter that gets the output of a command.
See what happens if you use this:
#Echo OFF
Pushd "C:\"
Call :sub a b c * d e
:sub
for %%f in (%1 %2 %3 %4 %5 %6 %7 %8) DO ECHO %%f
Pause&Exit
(The FOR prints all the files in current directory)
Then you need to do... :
#Echo OFF
Call :sub a b c* d e
:sub
FOR /F "tokens=*" %%a in ('Echo %*') DO (ECHO %%a)
Pause&Exit
I am trying to perform an action depending on this statements output:
wmic process where name="test.exe" | find "test.exe" /c
if the output is <=2 do echo two or less
if the output is >2 do echo more than two
How could this be achieved?
set them to variables then compare also you want switches before the search string =D
FOR /F "tokens=2 USEBACKQ delims=:" %%F IN (`command ^| find /C "test.exe"`) DO (
SET var=%%F
)
IF %var% LEQ 2 ECHO Two or Less
IF %var% GTR 2 ECHO More than Two
EDIT: (for Jeb <3)
FOR /F "tokens=2 USEBACKQ delims=:" %%F IN (`command ^| find /C "test.exe"`) DO (
SET var=%%F
)
IF %var% LEQ 2 (
ECHO Two or Less
) ELSE (
ECHO More than Two
)