Batch echo specific line - windows

This is my first post and I am not very skilled with batch so sorry if I really mess up.
Basically I'm working on a little batch script where once run, the user inputs a file path and line number and the specified line of the specified file will be output to the command line. I have all my variables and commands working, and the command to specify the line of the text file works fine, its just when I put my variables in it doesn't work. Now I'm guessing what I'm doing is obviously wrong since I'm new to batch, but anyway here's my code:
#echo off
color b
:top
title specified line copy tool
echo input full path to txt file
set /P filepath=">"
cls
echo what line would you like to copy?
set /P lineoriginal=">"
set /A actualline=%lineoriginal%-1
for /F "skip=%actualline% delims=" %%i in (%filepath%) do if not defined output set "output=%%i"
echo %output%
pause
See if you can see what I did wrong, thanks.

From this link Windows Batch file to echo a specific line number
you can call this function like that : Call:ReadNthLine <File> <nLine>
:ReadNthLine File nLine
FOR /F %%A IN ('^<"%~1" FIND /C /V ""') DO IF %2 GTR %%A (ECHO Error: No such line %2. 1>&2 & EXIT /b 1)
FOR /F "tokens=1* delims=]" %%A IN ('^<"%~1" FIND /N /V "" ^| FINDSTR /B /C:"[%2]"') DO ECHO.%%B
EXIT /b
And your code can be re-written like that :
#echo off
color b
:top
cls
title specified line copy tool
echo input full path to txt file
set /P "filepath=>"
cls
echo what line would you like to copy ?
set /P "nLine=>"
cls
CALL :ReadNthLine "%filepath%" %nLine%
PAUSE >NUL & goto:top
GOTO :EOF
::***************************************************************************************
:ReadNthLine File nLine
FOR /F %%A IN ('^<"%~1" FIND /C /V ""') DO IF %2 GTR %%A (ECHO Error: No such line %2. 1>&2 & EXIT /b 1)
FOR /F "tokens=1* delims=]" %%A IN ('^<"%~1" FIND /N /V "" ^| FINDSTR /B /C:"[%2]"') DO ECHO.%%B
EXIT /b
::***************************************************************************************

Related

How can I find last row that contains string in txt with cmd command

I want to find two different strings in .txt file. I need two scripts, first script to find last row that contains these strings together and second script to find last row that contains these strings seperately. I tried to write somethings but I go off the project.
This what i have tried so far as code :
#echo off
for /f %%i in ('find /v /c "" ^< deneme.txt') do set /a lines=%%i
echo %lines%
set /a startLine=%lines% - 1
more /e +%startLine% deneme.txt > temp.txt
find "ali" temp.txt|find "veli"
del temp.txt
Thanks for help.
#echo off
set "string1=ali"
set "string2=veli"
set "file=deneme.txt"
for /f "delims=" %%a in ('findstr /i "\<%string1%\>" %file% ^|findstr /i /v "\<%string2%\>" ') do set "out1=%%a"
for /f "delims=" %%a in ('findstr /i "\<%string2%\>" %file% ^|findstr /i /v "\<%string1%\>" ') do set "out2=%%a"
for /f "delims=" %%a in ('findstr /i "\<%string1%\>" %file% ^|findstr /i "\<%string2%\>" ') do set "out3=%%a"
echo last line with %string1%: "%out1%"
echo last line with %string2%: "%out2%"
echo last line with both: "%out3%"
for explanations, see for /? and findstr /?

List files inline in cmd

I'm scripting a .bat file that opens txt files after what user selects.
Bat file
#echo off
color 0a
:START
dir /b C:\pwd
set /p password= What are you looking for?
dir /b C:\pwd\%password%
set /p folder= What file?
type C:\pwd\%password%\%folder%.txt
echo.
GOTO NEXT
:NEXT
set /p exit= Something else? (Y/N)
if %exit% == Y ( GOTO START )
But the dir /b shows the folders/text file on a newline, but can i show the files inline, almost like this
| File-one.txt | File-two.txt | File-three.txt |
i know just the dir command but i dont want the 1 files 0bytes thingie etc.
You can use for %%f in ("*") do ... to match specific files, and then use set /p _OUTPUT=%*<nul as an echo command without a line feed. So, this should work as you requested...
#echo off
color 0a
:START
set /p _OUTPUT=^| <nul
for %%f in ("C:\pwd\*") do set /p _OUTPUT=%%f ^| <nul
set /p password= What are you looking for?
set /p _OUTPUT=^| <nul
for %%f in ("C:\pwd\%password%\*") do set /p _OUTPUT=%%f ^| <nul
set /p folder= What file?
type C:\pwd\%password%\%folder%.txt
echo.
GOTO NEXT
:NEXT
set /p exit= Something else? (Y/N)
if %exit% == Y ( GOTO START )
The idea is to build a List.
Something like this should help :
#echo off
setlocal enabledelayedexpansion
color 0a
set "reset=set $l="
:START
for /f "delims=" %%a in ('dir /b /a-a "C:\pwd"') do set "$l=!$l! ^| %%a"
echo !$l!
%reset%
set /p "password= Name of the directory you want to look IN ? : "
for /f "delims=" %%a in ('dir /b "C:\pwd\%password%\*.txt"') do set "$l=!$l! ^| %%a"
echo !$l!
%reset%
set /p folder= What file?
2>nul type "C:\pwd\%password%\%folder%.txt" || echo File not found
echo.
GOTO NEXT
:NEXT
set /p exit= Something else? (Y/N)
if %exit% == Y ( GOTO START )
dir /d /a-d "C:\pwd\%password%" | findstr /v "Bytes :"
dir /d takes care of proper formatting (depending on lenght of the longest filename, number of columns to fit to Screen, no line-wrapping within a filename).
remove /a-d if you want to show folders too.
You can also use /w instead of /d. The difference is horizontal vs. vertical sorting.
By default, sorting is with filenames, but you can change it with /oX

Find text in file and set it as a variable. Batch file

I try to find one line in whole text file. Next I need to set this line as a variable.
When I try do this:
set MY_VARIABLE=findstr /I "MY_TEXT" MY.FILE
echo %MY_VARIABLE%
The result of echo is findstr /I "MY_TEXT" MY.FILE, but I want to see result of this command line instead.
When I try do this – first enter in cmd:
for /F "delims=" %%a in ('findstr /I "MY_TEXT" MY.FILE') do set "batToolDir=%%a"
then enter in cmd:
echo "%batToolDir%"
I see an error:
the %%a variable is unsuspected
When I make a file SCRIPT.bat:
#echo off
for /F "delims=" %%a in ('set MY_VARIABLE=findstr /I "MY_TEXT" MY.FILE') do set "batToolDir=%%a"
echo "%batToolDir%"
I get this:
""
What is wrong? How to make this?
Almost done
For command line
for /F "delims=" %a in ('findstr /I "MY_TEXT" MY.FILE') do set "batToolDir=%a"
For batch file double the percent signs
for /F "delims=" %%a in ('findstr /I "MY_TEXT" MY.FILE') do set "batToolDir=%%a"

The ECHO command echo only show the last line of my file instead of shows each line

I want to show out of the console each line from a file. I try this:
findstr /v /b /c:" " <%1>toto
for /f "tokens=*" %%a in (toto) do set co=%%a
echo. %co%
Also this one:
findstr /v /b /c:" " <%1>toto
for /f "tokens=*" %%a in (toto) do (set co=%%a
echo. %co%
)
But the first way shows me only the last line of file and the second one doesn't show me anything.
Someone can explain me what's wrong in these latter and how to get in the 'co' variable each line printed on the console?
Thanks
you override co. to append to it try
set co=%co% %%a
Try this:
for /f "tokens=1*delims=:" %%a in ('findstr /n "^" "toto"') do echo %%b

How to count no of lines in text file and store the value into a variable using batch script?

I want to count the no of lines in a text file and then the value has to be stored into a environment variable. The command to count the no of lines is
findstr /R /N "^" file.txt | find /C ":"
I refered the question How to store the result of a command expression in a variable using bat scripts?
Then I tried,
set cmd="findstr /R /N "^" file.txt | find /C ":" "
I am getting the error message,
FIND: Parameter format not correct
How could i get rid of this error.
There is a much simpler way than all of these other methods.
find /v /c "" filename.ext
Holdover from the legacy MS-DOS days, apparently. More info here: https://devblogs.microsoft.com/oldnewthing/20110825-00/?p=9803
Example use:
adb shell pm list packages | find /v /c ""
If your android device is connected to your PC and you have the android SDK on your path, this prints out the number of apps installed on your device.
You could use the FOR /F loop, to assign the output to a variable.
I use the cmd-variable, so it's not neccessary to escape the pipe or other characters in the cmd-string, as the delayed expansion passes the string "unchanged" to the FOR-Loop.
#echo off
cls
setlocal EnableDelayedExpansion
set "cmd=findstr /R /N "^^" file.txt | find /C ":""
for /f %%a in ('!cmd!') do set number=%%a
echo %number%
Inspired by the previous posts,
a shorter way of doing so:
CMD.exe
C:\>FINDSTR /R /N "^.*$" file.txt | FIND /C ":"
The number of lines
Try it. It works in my console.
EDITED:
(the "$" sign removed)
FINDSTR /R /N "^.*" file.txt | FIND /C ":"
$ reduces the number by 1 because it is accepting the first row as Field name and then counting the number of rows.
Try this:
#Echo off
Set _File=file.txt
Set /a _Lines=0
For /f %%j in ('Find "" /v /c ^< %_File%') Do Set /a _Lines=%%j
Echo %_File% has %_Lines% lines.
It eliminates the extra FindStr and doesn't need expansion.
- edited to use ChrisJJ's redirect suggestion. Removal of the TYPE command makes it three times faster.
#Tony: You can even get rid of the type %file% command.
for /f "tokens=2 delims=:" %%a in ('find /c /v "" %_file%') do set /a _Lines=%%a
For long files this should be even quicker.
I usually use something more like this
for /f %%a in (%_file%) do (set /a Lines+=1)
for /f "usebackq" %A in (`TYPE c:\temp\file.txt ^| find /v /c "" `) do set numlines=%A
in a batch file, use %%A instead of %A
The perfect solution is:
FOR /F %%i IN ('TYPE "Text file.txt" ^| FIND /C /V ""') DO SET Lines=%%i
I found this solution to work best for creating a log file that maintains itself:
setlocal enabledelayedexpansion
SET /A maxlines= 10
set "cmd=findstr /R /N "^^" "filename.txt" | find /C ":""
for /f %%a in ('!cmd!') do set linecount=%%a
GOTO NEXT
:NEXT
FOR /F %%A IN ("filename.txt") DO (
IF %linecount% GEQ %maxlines% GOTO ExitLoop
echo %clientname% %Date% %Time% >> "filename.txt")
EXIT
:ExitLoop
echo %clientname% %Date% %Time% > "filename.txt"
EXIT
Environmental variables included are %clientname% the computername of the remote client %Date% is the current date and %Time% the current time. :NEXT is called after getting the number of lines in the file. If the file line count is greater than the %maxlines% variable it goes to the :EXITLOOP where it overwrites the file, creating a new one with the first line of information. if it is less than the %maxlines% variable it simply adds the line to the current file.
You don't need to use find.
#echo off
set /a counter=0
for /f %%a in (filename) do set /a counter+=1
echo Number of lines: %counter%
This iterates all lines in the file and increases the counter variable by 1 for each line.
The :countLines subroutine below accepts two parameters: a variable name; and a filename. The number of lines in the file are counted, the result is stored in the variable, and the result is passed back to the main program.
The code has the following features:
Reads files with Windows or Unix line endings.
Handles Unicode as well as ANSI/ASCII text files.
Copes with extremely long lines.
Isn’t fazed by the null character.
Raises an error on reading an empty file.
Counts beyond the Batch max int limit of (31^2)-1.
#echo off & setLocal enableExtensions disableDelayedExpansion
call :countLines noOfLines "%~1" || (
>&2 echo(file "%~nx1" is empty & goto end
) %= cond exec =%
echo(file "%~nx1" has %noOfLines% line(s)
:end - exit program with appropriate errorLevel
endLocal & goto :EOF
:countLines result= "%file%"
:: counts the number of lines in a file
setLocal disableDelayedExpansion
(set "lc=0" & call)
for /f "delims=:" %%N in ('
cmd /d /a /c type "%~2" ^^^& ^<nul set /p "=#" ^| (^
2^>nul findStr /n "^" ^&^& echo(^) ^| ^
findStr /blv 1: ^| 2^>nul findStr /lnxc:" "
') do (set "lc=%%N" & call;) %= for /f =%
endlocal & set "%1=%lc%"
exit /b %errorLevel% %= countLines =%
I know it looks hideous, but it covers most edge-cases and is surprisingly fast.
Just:
c:\>(for /r %f in (*.java) do #type %f ) | find /c /v ""
Font: https://superuser.com/questions/959036/what-is-the-windows-equivalent-of-wc-l
One nice surprise is for one who has git bash on his windows: just plain old linux wc -l <filename> will works for you there
In the below code, the variable name are SalaryCount and TaxCount
#ECHO OFF
echo Process started, please wait...
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Salary.txt"') do set SalaryCount=%%C
echo Salary,%SalaryCount%
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Tax.txt"') do set TaxCount=%%C
echo Tax,%TaxCount%
Now if you need to output these values to a csv file, you could use the below code.
#ECHO OFF
cd "D:\CSVOutputPath\"
echo Process started, please wait...
echo FILENAME,FILECOUNT> SUMMARY.csv
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Salary.txt"') do set Count=%%C
echo Salary,%Count%>> SUMMARY.csv
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Tax.txt"') do set Count=%%C
echo Tax,%Count%>> SUMMARY.csv
The > will overwrite the existing content of the file and the >> will append the new data to existing data. The CSV will be generated in D:\CSVOutputPath
You can pipe the output of type into find inside the in(…) clause of a for /f loop:
for /f %%A in ('
type "%~dpf1" ^| find /c /v ""
') do set "lineCount=%%A"
But the pipe starts a subshell, which slows things down.
Or, you could redirect input from the file into find like so:
for /f %%A in ('
find /c /v "" ^< "%~dpf1"
') do set "lineCount=%%A"
But this approach will give you an answer 1 less than the actual number of lines if the file ends with one or more blank lines, as teased out by the late foxidrive in counting lines in a file.
And then again, you could always try:
find /c /v "" example.txt
The trouble is, the output from the above command looks like this:
---------- EXAMPLE.TXT: 511
You could split the string on the colon to get the count, but there might be more than one colon if the filename had a full path.
Here’s my take on that problem:
for /f "delims=" %%A in ('
find /c /v "" "%~1"
') do for %%B in (%%A) do set "lineCount=%%B"
This will always store the count in the variable.
Just one last little problem… find treats null characters as newlines. So if sneaky nulls crept into your text file, or if you want to count the lines in a Unicode file, this answer isn’t for you.
You can also try
set n=0 & for /f "tokens=*" %a in (text.txt) do set/a n=!n!+1
echo !n!
You can also mark with a wildcard symbol * to facilitate group files to count.
Z:\SQLData>find /c /v "" FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_*.txt
Result
---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIFRS01_V1.TXT: 2041
---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIOST00_V1.TXT: 315938
---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIFRS00_V1.TXT: 0
---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_CNTPTF00_V1.TXT: 277

Resources