I wanted to sort numbers in a text file and write the same in another text file for the same I am using the command given below but I am not able to get the output can someone please help me with the same
sort -n test.txt /o output.txt
There is an error message coming up for this as Input file specified two times.
(nice exercise :) )
#echo off
setlocal enabledelayedexpansion
REM convert all numbers to the same lenght by adding leading spaces:
(for /f %%i in (input.txt) do (
REM 12 leading spaces:
set "Z= %%i"
REM take last 12 digits:
echo !Z:~-12!
))>temp.txt
REM sort it:'
sort temp.txt /O temp.txt
REM remove the spaces:
(for /f %%i in (temp.txt) do echo/%%i)>output.txt
del temp.txt
For sure (nice exercise :) ) !!!
Sort numbers in text file using command prompt but not using sort command!!**
#echo off && setlocal enabledelayedexpansion & cd /d "%~dp0"
for /f delims^=:^ tokens^=^2 %%i in ('find /c /v ";" input.txt')do set _cnt=%%i
2>nul (cd.>"%tmp%\_file_.tmp" & cd.>"output.txt") & for /f %%i in (input.txt)do echo/,%%i,>>"%tmp%\_file_.tmp"
for /l %%L in (1 1 99999)do find ",%%L," "%tmp%\_file_.tmp" >nul && (echo/%%L>>"output.txt" & call set /a "_cnt-=1" && if !_cnt! == 0 goto :~0)
:~0
timeout -1 & del "%tmp%\_file_.tmp" & type "output.txt"
:: to count lines / numbers that exist in the file, too, to be used as a run delimiter in for /l ::
for /f delims^=:^ tokens^=^2 %%i in ('find /c /v ";" input.txt')do set _cnt=%%i
:: create the 2 empty files and if they exist, delete the contents ::
2>nul (cd.>"%tmp%\_file_.tmp" & cd.>"output.txt")
:: create unique string for each file number/line "%tmp%\_file_.tmp" ::
for /f %%i in (input.txt)do echo/,%%i,>>"%tmp%\_file_.tmp"
rem :: performs a 1 in 1 to 99999 numeric loop and also finds ",number," in the file "%tmp%\_file_.tmp" ::
rem :: remove ",," (commas) from string, save (if any), only the variable number %%L in "output.txt"
for /l %%L in (1 1 99999)do find ",%%L," "%tmp%\_file_.tmp" >nul && (echo/%%L>>"output.txt" & call set /a "_cnt-=1" && if !_cnt! == 0 goto :~0)
:: for each occurrence, it will be subtracting 1 from the _cnt counter, so when it reaches zero it stops listing/fetching ::
echo/%%L>>"output.txt" & call set /a "_cnt-=1" && if !_cnt! == 0 goto :~0)
Related
So what I'm trying to do is create a find for multiple people where it in the text file it will say names and numbers like
Example of text file:
Beth
1234567891
Jay
2134456544
This is the best way I can explain what I'm trying to do:
#echo off
set "file=Test1.txt"
setlocal EnableDelayedExpansion
<"!file!" (
for /f %%i in ('type "!file!" ^| find /c /v ""') do set /a n=%%i && for /l %%j in (1 1 %%i) do (
set /p "line_%%j="
)
)
set /a Name=1
set /a Number=2
Echo Line_%Name%> %Name%.txt (Im trying to get this to say line_2 to say 1st line in the text file)
Echo Line_%Number%> %Name%.txt (Im trying to get this to say line_2 to say 2nd line in the text file)
:Start
set /a Name=%Name%+2 (These are meant to take off after 1 so lines 3,5,7,9 so on)
set /a Number=%Number%+2 (These are meant to take off after 2 so lines 4,6,8,10 so on)
Echo Line_%Name%
Echo Line_%Number%
GOTO :Start
so the outcome would be
In Beth.txt:
Beth
1234567891
So every name will be a file name and the first line in a file. I will change it later so I can do a addition in each text file.
Name: Beth
Number: 1234567891
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q65417881.txt"
rem make sure arrays are empty
For %%b IN (name number) DO FOR /F "delims==" %%a In ('set %%b[ 2^>Nul') DO SET "%%a="
rem Initialise counter and entry array
SET /a count=0
SET "number[0]=dummy"
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
IF DEFINED number[!count!] (SET /a count+=1&SET "name[!count!]=%%a") ELSE (SET "number[!count!]=%%a")
)
rem clear out dummy entry
SET "number[0]=dummy"
FOR /L %%c IN (1,1,%count%) DO (
rem replace spaces with dashes
SET "name[%%c]=!name[%%c]: =-!"
rem report to console rem report to console
ECHO Name: !name[%%c]! Number: !number[%%c]!
rem generate name.txt file
(
ECHO !name[%%c]!
ECHO !number[%%c]!
)>"%destdir%\!name[%%c]!.txt"
)
GOTO :EOF
You would need to change the values assigned to sourcedir and destdir to suit your circumstances. The listing uses a setting that suits my system.
I deliberately include spaces in names to ensure that the spaces are processed correctly.
I used a file named q65417881.txt containing your data for my testing.
The line data read from the file is assigned to %%a is assigned to and number[!count!] alternately. The data is retained in these arrays for use by further processing.
[Edited to include conversion of spaces within names to dashes]
If I understand correctly, you want to precede every second line with Number: + SPACE and every other line with Name: + SPACE. For this you do not need to store each line in a variable first, you can use a single for /F loop lo read the file line by line and process every line individually. There are two possibilities:
Temporarily precede every line with a line number plus : using findstr /N:
#echo off
rem // Loop through lines and precede each with line number plus `:`:
for /F "tokens=1* delims=:" %%K in ('findstr /N "^" "Test1.txt"') do (
rem // Calculate remainder of division by two:
set /A "MOD=%%K%%2" 2> nul
rem // Toggle delayed expansion to avoid issues with `!`:
setlocal EnableDelayedExpansion
rem // Conditionally return line string with adequate prefix:
if !MOD! neq 0 (
endlocal & echo Name: %%L
) else (
endlocal & echo Number: %%L
)
)
This will fail when a line begins with the a :.
Check whether numeric representation of current line string is greater than 0:
#echo off
rem // Loop through (non-empty) lines:
for /F "usebackq delims=" %%L in ("Test1.txt") do (
rem // Determine numeric representation of current line string:
set /A "NUM=%%L" 2> nul
rem // Toggle delayed expansion to avoid issues with `!`:
setlocal EnableDelayedExpansion
rem // Conditionally return line string with adequate prefix:
if !NUM! equ 0 (
endlocal & echo Name: %%L
) else (
endlocal & echo Number: %%L
)
)
This fails when a name begins with numerals and/or when a numeric line is 0.
And just for the sake of posting something different:
#SetLocal EnableExtensions DisableDelayedExpansion & (Set LF=^
% 0x0A %
) & For /F %%G In ('Copy /Z "%~f0" NUL') Do #Set "CR=%%G"
#For /F "Tokens=1,2* Delims=:" %%G In ('%__AppDir__%cmd.exe /D/V/C ^
"%__AppDir__%findstr.exe /NR "^[a-Z]*!CR!!LF![0123456789]" "Test1?.txt" 2>NUL"
') Do #(SetLocal EnableDelayedExpansion
(Set /P "=Name: %%I!CR!!LF!Number: " 0<NUL & Set "_="
For /F Delims^=^ EOL^= %%J In ('%__AppDir__%more.com +%%H "%%G"') Do #(
If Not Defined _ Set "_=_" & Echo %%J)) 1>"%%I.txt" & EndLocal)
This file should be run with the Test1.txt file in the current working directory. It is important that along side Test1.txt, there are no other .txt files with the same basename followed by one other character, (for example Test1a.txt or Test12.txt). Should you wish to change your filename, just remember that you must suffix its basename in the above code with a ? character, (e.g. MyTextFile.log ⇒ MyTextFile?.log).
I had the rare opportunity to verify that this script worked against the following example Test1.txt file:
Beth
1234567891
Jay
2134456544
Bob
2137856514
Jimmy
4574459540
Mary
3734756547
Gemma
6938456114
Albert
0134056504
good day, i have a folder with 400 files and i want to print a "name" from the filenames
this is the structure
ej:
20201323223_vendo.perfil01_17872513294967257_1601950878_live.mp4
20201323223__vvcastrillon_12_17949951031375250_1601939874_live.mp4
2020323123_yessromero.g_17849208194340047_1601945592_live.mp4
2020323223_ziizii_08_17979840166310477_1601929868_live.mp4
and what i need is
vendo.perfil01
_vvcastrillon_12
yessromero.g
ziizii_08
Im try to loop in the files and separate whit the _ and extract the 2 and 3 token numeral conditioning but the result is wrong and missing variables
#echo off
setlocal EnableDelayedExpansion
:loop
SET max=5000
for /F "delims=" %%I in ('dir "*_*_*.mp4" /A-D /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /L /V "\\outdir\\"') do (for /F "eol=| tokens=2,3 delims=_" %%J in ("%%~nI") do (SET "var="&for /f "delims=0123456789" %%a in ("%%K") do SET var=%%a
if defined var ( set nam=%%J_%%K ) else ( set nam=%%J )
)
echo/!nam!
)
timeout 10 > nul
goto loop
i think the answer is remove the first number before the _ then the string _xxxxxx_xxxxxxx_live.mp4 at the end but i dont know how read in reverse the tokens
tanks for any help
Since you have got different numbers of _-separated items in your file names and even adjacent _, so using for /F to split them into specific tokens with delims=_ is not the best choice.
I would use a standard for-loop instead, which receives modified file names, namely with each _ replaced by " " and enclosed within "", which leads to SPACE-separated partial name items. So:
20201323223_vendo.perfil01_17872513294967257_1601950878_live.mp4
is changed to:
"20201323223" "vendo.perfil01" "17872513294967257" "1601950878" "live.mp4"
before looping. Within the loop implement an index counter and just append those items to a buffer whose index numbers lie within a certain range that depends on the total number of items.
Here is an example script that demonstrates what I mean:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=%~dp0." & rem // (full path to target directory)
set "_MASK=*_*_*_*_live.mp4" & rem // (pattern to match file names)
set "_FILT=^[0123456789][0123456789]*_..*_[0123456789][0123456789]*_[0123456789][0123456789]*_live\.mp4$"
rem // (additional `findstr` filter for file names)
set /A "_POS=1" & rem /* (index of first `_`-separated item to extract;
rem `0` is the first item, `-1` is the last) */
set /A "_NUM=-4" & rem /* (number of `_`-separated items to extract;
rem `-1` means all up to the last item) */
rem // Change into target directory:
pushd "%_ROOT%" && (
rem // Loop through all matching non-hidden, non-system files:
for /F "delims= eol=|" %%F in ('
dir /B /A:-D-H-S "%_MASK%" ^| findstr /I /R /C:"%_FILT%"
') do (
rem // Store current file name, initialise item index, counter and buffer:
set "FILE=%%F" & set /A "IDX=-1, CNT=-1" & set "BUFF=_"
rem // Toggle delayed expansion to avoid troubles with `!`:
setlocal EnableDelayedExpansion
rem // Count number of items and store one less:
rem set "TEST=%FILE:_=" & set /A "CNT+=1" & set "TEST=%"
for %%I in ("!FILE:_=" "!") do set /A "CNT+=1"
rem // Determine item index position from given index and number:
if !_POS! lss 0 (set /A "BEG=CNT+_POS+1") else set /A "BEG=_POS"
if !_NUM! lss 0 (set /A "END=CNT+_NUM+1") else set /A "END=_POS+_NUM-1"
rem // Transport numbers over `endlocal` barrier:
for %%C in (!CNT!) do for %%B in (!BEG!) do for %%A in (!END!) do (
rem // Loop through `_`-separated items of file name:
for %%I in ("!FILE:_=" "!") do (
rem // Store current item, increment item index:
endlocal & set "ITEM=%%~I" & set /A "IDX+=1"
setlocal EnableDelayedExpansion
rem // Append current item to buffer if in range:
if !IDX! geq %%B if !IDX! leq %%A (
rem // Transport buffer over `endlocal` barrier:
for /F "delims=" %%E in ("BUFF=!BUFF!_!ITEM!") do (
endlocal & set "%%E"
setlocal EnableDelayedExpansion
)
)
)
)
rem // Return buffer:
echo(!BUFF:~2!
endlocal
)
rem // Return from target directory:
popd
)
endlocal
exit /B
Something like this should help:
#echo off
setlocal enabledelayedexpansion
for /f "tokens=1* delims=_." %%i in ('dir /b /s /a-d "*_*_*.mp4"2^>nul ^| findstr.exe /ILV "\\outdir\\"') do (
set "var=%%j"
for /f "tokens=2,* delims=_." %%a in ("%%j") do echo !var:_%%b=!
)
Keep in mind that using delims will also split on consecutive characters like double underscore. for those you need to predetermine which has double underscore and let the script add it for you.
#ECHO OFF
SETLOCAL
for %%a in (
20201323223_vendo.perfil01_17872513294967257_1601950878_live.mp4
20201323223__vvcastrillon_12_17949951031375250_1601939874_live.mp4
2020323123_yessromero.g_17849208194340047_1601945592_live.mp4
2020323223_ziizii_08_17979840166310477_1601929868_live.mp4
) do set "filename=%%a" &call :process&echo --------------------------------------
GOTO :EOF
:process
echo stage 1 %filename%
:: step 1 : delete all characters up to and including the first underscore
set "filename=%filename:*_=%"
echo stage 2 %filename%
:: step 2 : find all numeric strings of length 4 or more in remainder
call :strsgt4 %filename:_= %
:: step 3 : replace each numeric string of length 4 or more + preceding underscore with "/" (invalid filename character)
echo stage 3 %filename%
:proc3lp
if "%zapstrings%" neq " " for %%v in (%zapstrings%) do call set "filename=%%filename:_%%v=/%%"&call set "zapstrings=%%zapstrings: %%v=%%"&goto proc3lp
echo stage 4 %filename%
:: step 5 : Remove all charactersincluding and after the first "/"
for /f "delims=/" %%v in ("%filename%") do echo result %%v
goto :eof
:strsgt4
set "zapstrings= "
:strsgt4loop
set "test=%1"
if not defined test goto :eof
set "test=%test:~4%"
if defined test call :isnum %test%&if not defined notnumber set "zapstrings=%zapstrings% %1"
shift
goto strsgt4loop
:: Determine whether %1 is purely numeric
:isnum
SET "notnumber=9%~1"
FOR /l %%z IN (0,1,9) DO CALL SET "notnumber=%%notnumber:%%z=%%"
GOTO :eof
Really a question of working out what your rules are.
I decided that your rules were: string after the first underscore, until before the first subsequent underscore that precedes a numeric string or length greater than 3
The %%a loop simply submits a sequence of sample strings to :process
The inline comments should explain the remainder.
So I need a code that will take a text file (we'll cal it list.txt) and turn every line into a variable.
To give some context, I have some file names listed in list.txt, which adds and deletes file names occasionally by user request. I want the user of this code to be able to select which document they'd like to open using variables.
For example, if list.txt looks like this
list.txt
loading.txt
test1.txt
test2.txt
test3.txt
test4.txt
Then I'd like an automatic variable for every .txt listed. I then would add a simple if statement to open the file matched with the variable.
Am I making this too complicated for myself or is this the only way to do this?
EDIT:
I am not attempting something like this:
type list.txt
echo.
echo.
set /p GROUPSELECT= Please type out the FULL name of the group listed:
CD %grouplist%
type %GROUPSELECT%
It will display the file contents, and then display the specific file chosen by the input. I'd think that the variable might be easier to do more with later though, just a thought.
Edit2
I tried this:
#Echo OFF
FOR /F "Usebackq Delims=" %%a IN (
"list.txt"
) DO (
set jim=%%a
)
echo %jim%
PAUSE
%jim% will only be the last line in the text file, so how do I make the next step into making them all different?
Give this a try. I have commented each line of code that should explain what it is doing. Let me know if you need any further explanation.
#echo off
REM FOR commnd is parsing the output of the FINDSTR commands.
REM First FINDSTR command is finding non empty lines in the file
REM Second Findstr command is assigning a number to each line of the file
REM The output is split into two tokens and the number is assigned to %%G and the line of the file to %%H
for /F "tokens=1* delims=:" %%G IN ('findstr /V "^$" list.txt ^|findstr /N ".*"') DO (
REM create a variable of the lines in the file
set "file%%G=%%H"
REM Create a menu of the lines in the file
echo %%G %%H
REM Get the number of lines in the output
set "num=%%G"
)
REM Ask user to chose a number
set /P "filenum=Chose a file number 1 to %num%:"
REM Need to enable delayed expansion to use array variables
setlocal enabledelayedexpansion
REM Check if they type in a correct number and display the file
IF DEFINED file%filenum% type !file%filenum%!
endlocal
pause
Is this the sort of thing you're looking for?
#For /F "Delims==" %%# In ('Set # 2^>Nul')Do #Set "%%#="
#For /F Tokens^=1*Delims^=[]^ EOL^= %%# In ('Type "file.txt"^|Find /V /N ""'
)Do #Set "#%%#=%%$"&Echo( %%#. %%$
:Opt
#Echo(
#Set /P "Opt=Choose a document to open>"
#Set #|Findstr /B "#%Opt%=">Nul||GoTo :Opt
#Call Start "" "%%#%Opt%%%"
Just change the name of the text file containing your list on line 2 as needed.
#TheBoy your question is confusingly framed. If you DO NOT want the example you put in the edit, then can you better explain what you DO want??
Do you want to say iterate over the list file, and create a choice screen?
#(SETLOCAL EnableDelayedExpansion
ECHO OFF
SET "_ChoiceList_File=C:\Admin\ChoiceFile.txt"
REM Full Character List to populate Choices
SET "_CharList=0 1 2 3 4 5 6 7 8 9 A B C D E F N X"
)
CALL :Main
( ENDLOCAL
EXIT /B 0
)
:Main
REM Now we can Do Our Choices btu lets do it in a Sub Function.
CALL :MakeChoice _ChoiceResult
ECHO.
ECHO The Index Chosen Was: %_Chosen%
ECHO The Result Matched is: "%_ChoiceResult%"
REM ECHO Here you output "%_ChoiceResult%"
TYPE "%_ChoiceResult%"
GOTO :EOF
:MakeChoice
cls
color 1A
SET %~1="
SET "_Choices="
SET "_Chosen="
SET "_Amount="
SET "_Choice.17.Value=Next Set!"
SET "_Choice.18.Value=EXIT!"
SET "_Choice_Show_Next="
echo. Pick a File:
echo.========================
REM Create Numbered Array of Choices and output Choices to the Screen
FOR /F "tokens=* usebackq" %%A IN ("%_ChoiceList_File%") DO (
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=%%A"
IF !_Amount! EQU 16 (
SET /A "_Amount+=2"
CALL :MakeChoice "%~1"
IF DEFINED _Chosen (
IF !_Chosen! NEQ 17 (
REM IF !_Chosen! NEQ 18 (
GOTO :EOF
REM )
)
SET "_Amount="
SET "_Chosen="
)
)
)
IF NOT DEFINED _Chosen (
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=!"
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=EXIT!"
CALL :MakeChoice "%~1"
)
GOTO :EOF
:MakeChoice
CLS
ECHO.
SET "_Temp="
SET "_Choices="
SET /A "_Skipline= !_Amount! - 1"
REM Create Choice List to Display only the choices needed.
FOR %%A IN (%_CharList%) DO (
SET /A "_Temp+=1"
IF !_Temp! LEQ !_Amount! (
IF !_Temp! EQU !_Skipline! (
ECHO.
ECHO.=============================
)
IF DEFINED _Choice.!_Temp!.Value (
SET "_Choices=!_Choices!%%A"
CALL ECHO. %%A : %%_Choice.!_Temp!.Value%%
)
)
)
ECHO.
CHOICE /C !_Choices! /N /M "What File do you want to choose? "
SET "_Chosen=%ERRORLEVEL%"
SET "%~1=!_Choice.%_Chosen%.Value!"
GOTO :EOF
)
You can try this:
#echo off
setlocal enabledelayedexpansion
set jim=
for /f "delims=] tokens=1*" %%a in ('find /v /n "" ^<list.txt') do (
set jim=!jim! %%b
)
echo Select a file from !jim!
set /p file=
type !file!
pause
This will read all lines from the list.txt and return them within a variable !jim!.
I have a text file which containts stuff like
M test123
S test
M abc
and so on...
I'm trying to write a batch script that will do the following:
Read this text file, search every line for "M " (with spaces!) and then save the found line in a variable, delete the "M " and store the output in a seperate output.txt
So the output.txt should containt then following:
test123
S test
abc
Here's what I have so far:
SETLOCAL ENABLEDELAYEDEXPANSION
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (output_whole_check.txt) DO (
SET var!count!=%%F
findstr /lic:"M " > nul && (set var!count!=var!count!:~8%) || (echo not found)
SET /a count=!count!+1
)
ENDLOCAL
Or is there some easier way to solve that without any additional stuff installed on windows?
Try this one. It echoes all lines to output.txt with "M " replaced with nothing.
#echo off & setlocal
>output.txt (
FOR /F "usebackq delims=" %%I IN ("output_whole_check.txt") DO (
set "line=%%I"
setlocal enabledelayedexpansion
echo(!line:M =!
endlocal
)
)
Result:
test123
S test
abc
Or if your output_whole_check.txt is very large, it might be faster to loop over the lines using a for /L loop. for /L is more efficient than for /F. You just have to get a count of the lines to determine how many iterations to loop.
#echo off & setlocal
rem // get number of lines in the text file
for /f "tokens=2 delims=:" %%I in ('find /v /c "" "output_whole_check.txt"') do set /a "count=%%I"
<"output_whole_check.txt" >"output.txt" (
for /L %%I in (1,1,%count%) do (
set /P "line="
setlocal enabledelayedexpansion
echo(!line:M =!
endlocal
)
)
The result is the same output.
I've got bunch of text files with some content. First I wanted to number the lines globally. Then I extracted all lines that are duplicated somewhere (occur in any of given files at least twice). But now I need to mark all of these lines with the filename and line number of the first occurrence of this line. And now the funny part - it needs to be a windows batch file, using native windows tools. That's why I've got this problem to begin with.
So, to sum it up:
I have a file A with unique strings/lines, each of them is said to occur at least twice in given set of files.
I need to search these files and mark all occurrences of given line from A file with
-file name in which the line first occured
-line number in this file
This is my code with effort to number lines and format files.
#echo off
setlocal EnableDelayedExpansion
set /a lnum=0
if not [%1]==[] pushd %1
for /r %%F in (*.txt) do call :sub "%%F"
echo Total lines in %Files% files: %Total%
popd
exit /b 0
:Sub
set /a Cnt=0
for /f %%n in ('type %1') do (
set /a Cnt+=1
set /a lnum=!lnum!+1
echo ^<!lnum!^> %%n >> %1_ln.txt && echo ^<!lnum!^> >> %1_ln.txt && echo. >> %1_ln.txt
)
set /a Total+=Cnt
set /a Files+=1
echo %1: %Cnt% lines
#echo off
setlocal EnableDelayedExpansion
set lnum=0
if not "%~1" == "" pushd %1
rem "I've got bunch of text files..." (%%F is file name)
for /r %%F in (*.txt) do call :sub "%%F"
echo Total lines in %Files% files: %lnum%
popd
exit /b 0
:Sub "filename"
set Cnt=0
rem "... with some content." (%%n is line contents)
(for /f "usebackq delims=" %%n in (%1) do (
set /a Cnt+=1
rem "First I wanted to number the lines globally."
set /a lnum+=1
echo ^<!lnum!^> %%n
rem "Then I extracted all lines that are duplicated somewhere" (that were defined before)
if defined line[%%n] (
rem "I need to mark all of these lines with the filename and line number of the first occurrence of this line."
echo ^<!line[%%n]!^>
echo/
) else (
REM (Store the first occurrence of this line with *local* line number and filename)
set line[%%n]=!Cnt!: %1
)
)) > "%~PN1_ln.txt"
set /A Files+=1
echo %1: %Cnt% lines
exit /B
The above Batch program ignore empty lines in the input files and fail if they contain special Batch characters, like ! & < > |; this limitation may be fixed if required.
#ECHO OFF
SETLOCAL
FOR /f "delims=" %%s IN (A) DO (
SET searching=Y
FOR /f "delims=" %%f IN (
'dir /s /b /a-d *.txt') DO IF DEFINED searching (
FOR /f "tokens=1delims=:" %%L IN (
'findstr /b /e /n /l /c:"%%s" ^<"%%f"') DO IF DEFINED searching (
ECHO Line %%L IN "%%f" FOUND "%%s"
SET "searching="
)
)
)
Here's the meat of a routine that should do what you appear to be looking for - and that's as clear as mud.
It looks through the "A" file for each string in turn, assigns the string to %%s and sets the flag searching
Then it looks through the file list, assigning filenames to %%f
Then it executes a findstr to find the /c:"%%s" complete string %%s (including any spaces) in /l or literal mode (ie. not using regular expressions) for a line that both /b and /e begins and ends with the target (ie exactly matches) and /n numbers those lines.
The output of findstr will be in the format linenumber:linecontents so if this line is examined by the FORwith the option "delims=:" then the partion up to the first : is assigned to to %%L
So - %%L contains the line#, %%f the filename, %%s the string
Clearing searching having detected this line by setting its value to [nothing] means it's not NOT DEFINED hence no further lines will be reported from the current file, and no further filenames will be examined.
Now if you want to get a listing of ALL of the occurrences of the target lines, all you need to do is to REM-out the SET "searching=" line. Searching will then never be reset, so each line in each file is reported.
If you want some other combination, please clarify.
I have absolutely no idea whatever what you mean by "marking" a line.
#ECHO OFF & setlocal
for /f "tokens=1*delims==" %%i in ('set "$" 2^>nul') do set "%%i="
for %%a in (*.txt) do (
for /f %%b in ('find /v /c "" ^<"%%a"') do echo(%%b lines in %%a.
set /a counter=0, files+=1
for /f "usebackqdelims=" %%b in ("%%~a") do (
set /a counter+=1, total+=1
set "line=%%b"
setlocal enabledelayedexpansion
if not defined $!line! set "$!line!=%%a=!counter!=!line!"
for /f "delims=" %%i in ('set "$" 2^>nul') do (if "!"=="" endlocal)& set "%%i"
)
)
echo(%total% lines in %files% files.
for /f "delims=" %%a in (a) do set "#%%a=%%a"
for /f "tokens=2,3*delims==:" %%i in ('set "$" 2^>nul') do (
if defined #%%k echo("%%k" found in %%i at line %%j.
)
Script can handle !&<>|%, but not =.