how get the same keyword in file - batch-file

I have a list file
MFC_530_18MM_007_F0
MFC_520_18MM_008_F0
MFC_430_18MM_001_F1
MFC_270_18MM_002_F1
MFC_270_18MM_003_F1
MFC_720_18MM_004_F1
MFC_130_18MM_005_F1
MFC_540_18MM_006_F1
MFC_BT580_18MM_007_F1
MFC_530_18MM_008_F1
MFC_MP110_18MM_009_F1
MFC_AAC1_18MM_010_F1
I want to get the same name
ex:
MFC_530_18MM
MFC_520_18MM
MFC_430_18MM
MFC_270_18MM
MFC_270_18MM
MFC_720_18MM
MFC_130_18MM
MFC_540_18MM
MFC_BT580_18MM
MFC_530_18MM
MFC_MP110_18MM
MFC_AAC1_18MM
I have this code:
#echo off
set "R_Str_f=_0.*"
set "R_Str_fed="
setlocal enableDelayedExpansion
(
for /f "tokens=1* delims=:" %%a in ('findstr /n "^" source.txt') do (
set "line=%%b"
if defined line set "line=!line:%R_Str_f%=%R_Str_fed%!"
echo(!line!
)
)> output.txt
I want this code to remove the last character and then remove duplicate keywords but it does not work

not sure which OS you're using.
on Unix/Linux and SHELL you can try to use the "_" as a field separator (FS)
cat yourfile | awk 'FS="_" { print $1"_"$2"_"$3}'

If the requirement is to result in the first three (3) items separated by LOW LINE (underscore) characters, this might work.
#powershell -NoLogo -NoProfile -Command ^
"Get-Content -Path '.\in.txt' | ForEach-Object {($_ -split '_')[0..2] -join '_'}"
Result:
PS C:\src\t\so68080140> .\doit.bat
MFC_530_18MM
MFC_520_18MM
MFC_430_18MM
MFC_270_18MM
MFC_270_18MM
MFC_720_18MM
MFC_130_18MM
MFC_540_18MM
MFC_BT580_18MM
MFC_530_18MM
MFC_MP110_18MM
MFC_AAC1_18MM

Given that your question intent appears to be to replace everything from and including _0 with nothing, does this help?
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
( For /F UseBackQ^ Delims^=^ EOL^= %%G In ("source.txt") Do (
Set "LineContent=%%G"
SetLocal EnableDelayedExpansion
For /F UseBackQ^ EOL^=^|^ Delims^=^| %%H In (
'!LineContent:_0^=^|!'
) Do EndLocal & Echo(%%H
)
) 1>"output.txt"
For the above example code to work, I have assumed, and therefore it is a requirement, that your initial strings do not include any | characters.
If you are using Windows 10, and do not mind what order your output file list is in, then you could probably perform the entire task, i.e. with duplicates removed, like this:
#Echo Off
SetLocal EnableExtensions
(
For /F UseBackQ^^^ Delims^^^=^^^ EOL^^^= %%G In ("source.txt") Do #(
Set "LineContent=%%G"
%SystemRoot%\System32\cmd.exe /D /C "Echo(%%LineContent:_0=&:%%"
)
) | %SystemRoot%\System32\sort.exe /Unique 1>"output.txt"

Related

Trying to use windows batch to remove all extra spaces while leaving exactly one space between values

I have a text file that contains lots of values on multiple lines with a different amount of spaces between values. Some spacing is 4, 6, 7, 9, etc. I have this code written but it only works for removing odd numbers of spaces (and leaving one space) which means that if I have 4 spaces between values (an even amount) I have no required space left.
Edit: max spacing is 13 and values per line are not the same.
Example text file:
123.000 345.555 # 777.4560000 1.55555 66.878444
333.444 555.4848 999.758584 | 34.3737373
This is what I want after the fix:
123.000 345.555 777.4560000 1.55555 66.878444
333.444 555.4848 999.758584 34.3737373
This is what I am getting with my code below:
123.000345.555 777.45600001.55555 66.878444
333.444555.4848 999.758584 34.3737373
How do I set spacing to one space between every value regardless of the amount of spaces? I am also removing the # and | symbols as well.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
> "conv_output_clean.txt" (
for /F "usebackq delims=" %%L in ("conv_output.txt") do (
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LINE= !LINE: =!"
set "LINE=!LINE:#=!"
set "LINE=!LINE:|=!"
echo(!LINE!
endlocal
)
)
endlocal
exit /B
Based upon your provided text content, and ignoring your | and # characters being removed, the following example should replace all concurrent space characters with a single one:
#SetLocal EnableDelayedExpansion
#(For /F UseBackQ^ Delims^=^ EOL^= %%G In ("conv_output.txt") Do #(Set "_="
For %%H In (%%G) Do #If Not Defined _ (Set "_=%%H ") Else Set "_=!_!%%H "
Echo !_!)) 1> "conv_output_clean.txt"
If you want to also remove the | and # characters, then the following modification should work with your provided content:
#SetLocal EnableDelayedExpansion
#(For /F UseBackQ^ Delims^=^ EOL^= %%G In ("conv_output.txt") Do #(
Set "_="&Set "#=%%G"&Set "#=!#:|=!"
For %%H In (!#:#^=!) Do #If Not Defined _ (Set "_=%%H ") Else Set "_=!_!%%H "
Echo !_!)) 1> "conv_output_clean.txt"
Yet another way, output redirection left for the reader to add.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%L in ("conv_output.txt") do (
set "line="
for %%M in (%%L) do (
if "%%M" neq "#" if "%%M" neq "|" (
if defined line set "line=!line! "
set "line=!line!%%M"
)
)
echo(!line!
)
[ EDIT ] Sample run output.
C:\etc>type conv_output.txt
123.000 345.555 # 777.4560000 1.55555 66.878444
333.444 555.4848 999.758584 | 34.3737373
C:\etc>conv_output.cmd
123.000 345.555 777.4560000 1.55555 66.878444
333.444 555.4848 999.758584 34.3737373
C:\etc>
You can wind down number of spaces step by step using a while-like loop (or until-like loop). Unfortunately, we cannot use :label inside a command block enclosed in () parentheses so call a subroutine as follows:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
>"conv_output_clean.txt" (
for /F "usebackq delims=" %%L in ("conv_output.txt") do (
set "LINE=%%L"
call :removeAddChars
setlocal EnableDelayedExpansion
echo(!LINE!
endlocal
)
)
endlocal
exit /B
:removeAddChars
set "LINE=%LINE:#=%"
set "LINE=%LINE:|=%"
:remove2Spaces
set "LINE=%LINE: = %"
set "_LINE=%LINE: = %"
if "%_LINE%"=="%LINE%" goto :eof
goto :remove2Spaces
Output:
type conv_output.txt
123.000 345.555 # 777.4560000 1.55555 66.878444
333.444 555.4848 999.758584 | 34.3737373
.\SO\63063411.bat
type conv_output_clean.txt
123.000 345.555 777.4560000 1.55555 66.878444
333.444 555.4848 999.758584 34.3737373
This will work with up to 16 spaces:
#echo off
setlocal enabledelayedexpansion
for /f "usebackq delims=" %%a in ("conv_output.txt") do (
set "LINE=%%~a"
set "LINE=!LINE:#=!"
set "LINE=!LINE:|=!"
set "LINE=!LINE: = !"
set "LINE=!LINE: = !"
set "LINE=!LINE: = !"
set "LINE=!LINE: = !"
echo !line!
)
It replaces 9 spaces with a single space, then 5, 3, and 2. If you add 17 you can (I believe) replace up to 32 spaces. Note it is imperative to remove the # and | first.
Another idea is to use call and shift:
#echo off
setlocal enabledelayedexpansion
for /f "usebackq delims=" %%a in ("conv_output.txt") do (
set "lineinput=%%~a"
set "lineinput=!lineinput:#=!"
set "lineinput=!lineinput:|=!"
call :process !lineinput!
)
goto :eof
:process
set lineoutput=%~1
shift
:loop
if "%~1"=="" echo %lineoutput%&&goto :eof
set lineoutput=%lineoutput% %~1
shift
goto :loop
I'll leave it up to you to put this into your code.
Here is one more algorithm as designed by Jeb on DosTips.com
#echo off
setlocal EnableExtensions DisableDelayedExpansion
> "conv_output_clean.txt" (
for /F "usebackq delims=" %%L in ("conv_output.txt") do (
set "str=%%L"
setlocal EnableDelayedExpansion
set "str=!str:#=!"
set "str=!str:|=!"
set ^"str=!str: =a !"
set ^"str=!str: a =!"
set ^"str=!str:a = !"
echo(!str!
endlocal
)
)
endlocal
exit /B
Here is Jeb's explanation from that post. In Jeb's example it was replacing commas. So wherever he mentions a comma, it equates to the space in this users desired output
I want to use the replacing of a search pattern with nothing to remove all but one comma.
Obviously this can't work with simply replacing ","->"".
So I create first a better pattern
"," -> "a,,"
abc,,,,cba,,,,end
will be expanded to
abca,,a,,a,,a,,cbaa,,a,,a,,a,,end
Then each ",a," will be replaced with nothing
abca,,a,,a,,a,,cbaa,,a,,a,,a,,end
->
abca,,cbaa,,end
Now, exactly one pattern remains and will be replaced with the rule "a,," -> ","
And just to show the efficiency of some of the code answers, I did a test with a 2,000 line file.
JosezF: 0 Days 0 Hours 0 Minutes And 5 Seconds
Jeb: 0 Days 0 Hours 0 Minutes And 0 Seconds
Compo: 0 Days 0 Hours 0 Minutes And 0 Seconds
The code I used from Jeb and Compo's code are quite efficient. Less than 1 second for each of them.
Here is an alternative approach that is foolproof against empty lines/ lines that contain !
#echo off
SETLOCAL DisableDelayedExpansion EnableExtensions
>"process.txt" (FOR /F "delims=" %%L in ('
""%__APPDIR__%FINDSTR.EXE" /N "^^" example.txt"
') do (
set "lnCont=%%L"
SETLOCAL EnableDelayedExpansion
set "lnCont=!lnCont:*:=!"
FOR %%C in (^| #) do if DEFINED lnCont set "lnCont=!lnCont:%%~C=!"
if DEFINED lnCont FOR /F delims^=^ eol^= %%T in (^"!lnCont:^ ^=^
%=DO NOT REMOVE ME=%
!^") do if DEFINED proc (set "proc=!proc! %%T") ELSE set "proc=%%T"
echo(!proc!
ENDLOCAL
))
The loop:
parses the output of FINDSTR /N, line by line
replace all SPACEs with linefeeds
FOR /F ignore empty lines, therefore consecutive spaces are treated as one
One more way...
Get-Content .\conv_output.txt |
ForEach-Object { ($_ -replace '\|','') -replace '\s+',' ' }
Running from a cmd.exe shell or .bat file script...
powershell -NoLogo -NoProfile -Command ^
"Get-Content .\conv_output.txt |" ^
"ForEach-Object { ($_ -replace '\|','') -replace '\s+',' ' }"

Removing carriage returns from a text file using a batch file based on a value

I have a text file that I would like to edit and therefore would like to remove the last line. I have the following code for this:
for /f "delims=" %%a in (input.txt) do (
echo/|set /p ="%%a%"
)>>output.txt
input:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
output:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Now I would like to edit the data in groups for example by the first value, so that I have the following output:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
If I replace the FOR /F "delims=" %%a in (input.txt) do … loop with an equivalent FOR %%a in … loop:
#ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
set "_gruppeName="
(
for %%a in (
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
) do (
for /f "tokens=1 delims=;" %%A in ("%%~a") do (
if /I NOT "%%~A"=="!_gruppeName!" (
if defined _gruppeName echo(
set "_gruppeName=%%~A"
)
)
echo/|set /p ="%%~a"
)
echo(
)>>output.txt
REM debugging output follows
type output.txt
Output:
1st run: 2>NUL del output.txt & D:\bat\CR\61816520.bat
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Next run: D:\bat\CR\61816520.bat
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Your question is not clear
based on ... the first value (GRUPPEA)
is it SORTed? or just write duplicates on the same line?
#echo off
SETLOCAL EnableExtensions EnableDelayedExpansion
::VARIABLES
set "in=input.txt" IN file
set "out=output.txt" OUT file
set/a"#lines=0"
set "gruppe="
set "prevContent="
::Count lines
FOR /F %%L in ('
"findstr /N "^^" "%in%" %= do not skip empty lines =%"
') do set/a"#lines+=1" %= Get the # of lines =%
::Read IN via SET /P #LINES number of times
::Bangs (!) will be lost
<"%in%" >"%out%" (FOR /L %%# in (1 1 %#lines%) do (
set "data=" ::clear DATA
set/p"data=" ::read from IN
FOR /F tokens^=1^ delims^=^;^ eol^= %%T in ("!data!") do set "gruppe=%%T"
if NOT "!prevContent!" == "!gruppe!" (
set "prevContent=!gruppe!"
echo(
)
<nul set/p"=!data!" ::does not work with leading space, tabs, or equal signs
)) %= read file by lines via SET /P =%
exit /b
The script counts the number of lines using FINDSTR /N and a FOR /F loop to count the # of lines, which is required to execute SET /P that many times.
Tips:
Use ECHO( instead of the problematic ECHO.
Using a pipe | is very slow, as described by #jeb here. Use <nul instead

Batch replacing everything after the last underscore character to the beginning of the file extension

So I want to replace this:
Brand_Name_18.jpg
With this
Brand_Name_close-up.jpg
I tried
#echo off &setlocal
for /f "tokens=1-3*delims=_" %%i in ('dir /b /a-d *.jpg ^| find /i /v "_0_"') do ren "%%i_%%j" "%%i_%%j_0_"
but had no success. I also played with the PowerShell and was able to replace some characters there, but not particularly what I want. The characters I wanted to add were appearing at the end of the file extension, which broke everything...
Dir | rename-item -newname { $_.Name + "_close-up }
.
get-childitem -recurse | rename-item -newname { $_.name -replace "_","_close-up" }
I would also like to make the batch appear in the window when I right click, so I could apply it to a file that I need it to be applied on. So that has probably something to do with the registry, right?
SOLUTION thanks to T3RR0R
#echo off & Setlocal EnableDelayedExpansion
REM Change Directory and Remove /R recursive switch as / if necessary.
For /R %%A in (Brand_Name_*.jpg) do (
REN %%~nxA Brand_Name_close-up.jpg
)
pause
This will do the trick. If you're processing a large subset of files, you'll be best off modifying it to rename using a suitable naming convention that doesn't require input.
#echo off & Setlocal EnableDelayedExpansion
Goto :Main
:ModString <string length> <string> <target substring> <prefix VarName> <Substring Length>
Set String=%2
For /L %%L in (%1,-1,1) do (
Set Test=!String:~%%L,%5!
If /I "!Test!"=="%3" (
Set %4=!String:~0,%%L!
Exit /B
)
)
Set /P "prefix=%3 not found. Set prefix:"
Exit /B
:StrLen <resultVar> <string>
(
Setlocal EnableDelayedExpansion
(set^ tmp=%~2)
If Defined tmp (
Set "len=1"
For %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) Do (
If "!tmp:~%%P,1!" NEQ "" (
Set /a "len+=%%P"
Set "tmp=!tmp:~%%P!"
)
)
) else (
Set "len=0"
)
)
(
ENDLOCAL
Set "%~1=%len%"
exit /b
)
:Main
Set /P "Searchfolder=< Drop & Drag or Enter Parent Folder:"
IF Not Exist "!Searchfolder!" Goto :Main
Set /P "Extension=Extension:"
Set /P "SearchString=Enter String to Locate:"
For %%V in (Extension SearchString) do IF "!%%V!"=="" Goto :Main
For /R %%A in (*!SearchString!*.!Extension!) do (
Call :StrLen substringLen "!SearchString!"
Call :StrLen prefixLen "%%~nA"
Call :ModString !prefixLen! %%~nA !SearchString! prefix !substringLen!
Echo(Rename: %%~nxA
Set /P "Newstring="
REN %%~nxA !prefix!!SearchString!!Newstring!%%~xA
)
CHOICE /N /C ny /M "more N/Y?"
IF errorlevel 2 (
Set Extension=
Set Searchstring=
Goto :main
)
exit
Update
With the only known in your usage being that the underscore is the last instance in the name / string that you wish to retain in the new filename, the function needs to be modified to find it's position in the string using a String Length function in order to Modify the string from that point using Substring Modification.
The StrLen function is the work of Jeb
I've modified the code to now take a bit more input, and be more flexible. You can now use it with other extensions and define the String to search for at runtime.

How to delete the last character of a file

I use this batch files to create a list of files
#echo off
(for /f "delims=" %%a in ('dir/b/a-d *.tex') do echo %%a,)>liste.dat
the result is like this
file1.tex,
file2.tex,
file3.tex,
...
lastfile.tex,
how do I delete the last comma?
#echo off
SETLOCAL EnableDelayedExpansion
SET "in="
(
for %%a in (*.tex) do (
IF "!in!"=="" (
set in=%%a
) ELSE (
echo !in!,
set in=%%a
)
)
echo !in!
)>liste.dat
#echo off
setlocal EnableDelayedExpansion
set "comma="
< NUL (
for %%a in (*.tex) do (
set /P "=!comma!%%a"
set comma=,^
%Empty line%
)
echo/
) > liste.dat
EDIT: Reply to a comment
Ops! When I was developing this code I just displayed the output in the screen, where it looks correct:
C:\> test.bat
One.tex,
Three.tex,
Two.tex
Even if the output is sent to a file and the file is displayed in the screen, the output looks correct:
C:\> test.bat > output.txt
C:\> type output.txt
One.tex,
Three.tex,
Two.tex
However, the character inserted after each comma is just a LF so if this file is open with Notepad, the LF's are not converted to "end of lines"; just cmd.exe screen output converts LF to CR+LF pair ("cooked output" instead of "raw output").
The way to fix this detail is inserting a complete CR+LF pair after each comma:
#echo off
setlocal EnableDelayedExpansion
for /F %%a in ('copy /Z "%~F0" NUL') do set "CR=%%a"
set "comma="
< NUL (
for %%a in (*.tex) do (
set /P "=!comma!%%a"
set comma=,!CR!^
%Empty line%
)
echo/
) > liste.dat
The problem is that you don't know how many lines/files there will be. So you'll have to use two loops the way your code is written. One to count the lines and one to perform the operations. It's way easier to have a different handling for the first line instead of the last one. So how about this:
#echo off
SETLOCAL EnableDelayedExpansion
SET /a i=0
(for /f "delims=" %%a in ('dir /b/a-d *.tex') do (
IF !i!==1 (
echo ,%%a
) ELSE (
ECHO %%a
SET /a i=1
)
)
)>liste.txt
This will generate something like this:
file1.tex
,file2.tex
,file3.tex
...
,lastfile.tex
This seems equivalent to your desired output. If you actually want to have , at the end of the lines instead of at the beginning of the next one, tell me and I'll update the code but it'll be quite ugly.

New line as a delimeter of FOR loop

I am new to batch script, and I am trying to parse a file that has key value (kind) of pairs delimited by new line. For example:
the value of abc
1234
the value of def
5678
the value of ghi
9876
I would like to read this file using new line as delimited so that I can access the values.
Something like
for /f "tokens=1,2,3 delims='\n'" %%i in ('findstr /C:the value of abc 'filepath') do echo %%j
I just put it here as an option:
for /F delims^=^ eol^= %%i in ('findstr /C:the value of abc 'filepath') do echo %%i
You can't set 'new line' as delimiter. Try this:
#echo off &setlocal
for /f "tokens=1*delims=:" %%i in ('findstr /NC:"the value of abc" "filepath"') do set /a count=%%i
if defined count for /f "skip=%count%tokens=1*delims=:" %%i in ('findstr /N "^" "filepath"') do if not defined value set "value=%%j"
echo.%value%
endlocal
#ECHO OFF
SETLOCAL
SET "prevline="
FOR /f "delims=" %%z IN (tvabc.txt) DO (
IF DEFINED prevline (
FOR /f "tokens=1-6" %%a IN ('echo %%prevline%% %%z') DO (
ECHO %%a %%b %%c %%d %%e %%f
)
SET "prevline="
) ELSE (SET prevline=%%z)
)
should do the job, if you require each token from two successive lines to be output. Would be much easier if we had a listing of the required output rather than having to guess from code that doesn't work.
Essentially, this code saves the contents of one line then detects that the second has been read by the fact that the variable holding the previous line is defined. Under those circumstances, for/f is used to tokenise the concatenation of the two lines.
Not sure what you're going to do with those Name/Value pairs after you get them, but if you're going to do it in Powershell, do it right and start by creating objects:
$file = 'c:\somedir\somefile.txt'
[regex]$regex = #'
(?ms)the value of (\S+)
(\d+)
'#
#Choose one
$text = Get-Content $file -Raw # V3 Only
$text = [IO.File]::ReadAllText($file) # V2 or V3
$regex.matches($text) |
foreach {
New-object PSObject -Property #{
Name = $_.groups[1].value
Value = $_.groups[2].value
}
}|
Select Name,Value |
Format-Table -AutoSize
Name Value
---- -----
abc 1234
def 5678
ghi 9876
What do you think of that? In powershell:
(get-content .\essai.txt)[(Select-String .\essai.txt -Pattern "the value of abc").LineNumber]
It displays the next line after the pattern.
I normally use the given batch command, to read each line in file
FOR /F "delims=" %%G IN (test.txt) DO (
ECHO %%G
)
Here, "delim=" does the trick.

Resources