0

I am creating a list using a file with a for loop. Is there a way of not including a comma on the last value of my loop?

Here is the code:

for /F %%a in (test.txt) do (set comma=,& echo %%a !comma!) >> Output.txt

where test.txt contains a list:

ABC 
123 
EG

and i hope to achieve something like this:

ABC,
123,
EG
aschipfl
  • 33,626
  • 12
  • 54
  • 99
Alan15000
  • 3
  • 1

3 Answers3

1

Just a basic method. test the number of lines, only add a comma if the line number does not match the total number of lines:

@echo off
setlocal enabledelayedexpansion
set "comma=,"
set counter=0
for /F %%i in ('type test.txt ^| find /C /V "^"') do set cnt=%%i
(for /F %%a in (test.txt) do (
    set /a counter+=1
    if !counter! lss %cnt% (
      echo %%a%comma%
    ) else (
      echo %%a
   )
))> Output.txt
Gerhard
  • 22,678
  • 7
  • 27
  • 43
  • 1
    If there is an empty line the counter will never reach the total number of lines; not an issue with the data from the question though… – aschipfl Oct 07 '21 at 14:23
  • @aschipfl, correct. Hence I asked op the question in a comment and after clarification I just posted this example. – Gerhard Oct 07 '21 at 19:40
1

What you can do is set the FOR variable to an environmental variable. Then only output that line when the previous line is present. Then output the last line outside of the loop.

@echo off
setLocal enableDELAYedeXpansioN
set "line="
for /f "delims=" %%a in (test.txt) do (
    if defined line echo !line!,
    set "line=%%a"
) >>Output.txt
(echo %line%)>>Output.txt
Squashman
  • 13,649
  • 5
  • 27
  • 36
0

This answer might be more of academic value, but I could not resist to give it a try using the findstr command that is capable of searching beyond line-breaks, which I intend to use for retrieving all but the last line first and the last line alone later.

The tricky part was to find a way to work around the problem that the search character . unexpectedly matches the end-of-file as recorded in this post. I would expect the following code to match the last line but it fails (the string !_LF!!_CR!*!_LF! matches lines preceding empty ones as there are two consecutive line-breaks, and the string !_LF!. should match lines preceding non-empty ones, excluding the last one as there is either no line-break at all or such is not followed by anything, but this fails):

rem /* Delayed expansion is enabled, the variables `_LF` and `_CR`
rem    are set to line-feed and carriage-return characters, resp.: */
findstr /V "!_LF!!_CR!*!_LF! !_LF!." "test.txt"

Therefore, I had to use a way around that, unfortunately having to use multiple findstr commands, each of which reading the file on its own:

rem /* Test for trailing line-break using `$`, which anchors to carriage-return;
rem    due to this, Unix-style text files are not supported by this method: */
> nul findstr /V "$" "test.txt" && (
    rem // There is no trailing line-break, so `$` does not match the last line:
    findstr "$" "test.txt"
) || (
    rem /* There is a trailing line-break, so return all lines that precede two line-breaks
    rem    with something (except line-breaks since `.` does not match such) in between: */
    findstr "!_LF!.*!_CR!!_LF!" "test.txt"
)

This is the full approach:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE=.\test.txt" & rem // (path to target file)
(set ^"_LF=^
%= blank line =%
^") & rem // (this gathers a line-feed character)
rem // Gather a carriage-return character:
for /F %%Z in ('copy /Z "%ComSpec%" nul') do set "_CR=%%Z"

rem // Iterate through lines of text line by line:
for /F delims^=^ eol^= %%L in ('
    rem/ First test for final line-break, then do specific search: ^
        ^& ^> nul findstr /V "$" "%_FILE%" ^
        ^&^& ^(findstr "$" "%_FILE%"^) ^
        ^|^| ^(cmd /V /C findstr "!_LF!.*!_CR!!_LF!" "!_FILE!"^)
') do (
    rem /* Here all but the last lines are enumerated, which are then output
    rem    with a comma `,` appended; note that empty lines are ignored: */
    echo(%%L,
)
rem // Here the last line is returned, independent from final line-break:
setlocal EnableDelayedExpansion
findstr /V "$" "!_FILE!" || findstr /V "!_LF!.*!_CR!!_LF!" "!_FILE!"
endlocal

endlocal
exit /B
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Thanks @aschipfl for the answer, its really detailed and thorough! Appreciate an alternative approach :) – Alan15000 Oct 07 '21 at 13:12