0

I have a bunch of .txt files:

  • 1.txt containing string "1"
  • 2.txt containing string "2"
  • 3.txt containing string "3"

I need to combine them to get "result.txt" containing this:

1
2
3

I used echo. as a new line character in a batch:

for /r %%i in (*.txt) do (
type %%i>> result.txt
echo.>> result.txt
)

But in "result.txt" I'm getting this:

1
2.
3.

So, echo. actually works perfectly well for the first (1.txt) file, but it also puts a . before new lines for the rest of the files.

Can someone please fix batch code for me?

P.S.: the problem occurred because .txt files were located in different subfolders - that's why I used for /r initially (it doesn't always work, see details below!).

  • I can't reproduce, the result I get using Windows 10 CMD is exactly 9 bytes; in hex: `31 0D 0A 32 0D 0A 33 0D 0A` – Peter B Dec 10 '20 at 16:43
  • Can't reproduce that either, but use `echo/` rather than `echo.` (the latter initiates a file system access, and when a file `echo.` (no extension) is found, it fails). How are the input files encoded? ASCII/ANSI or Unicode? – aschipfl Dec 10 '20 at 17:47
  • @aschipfl I just create blank .txt from Windows 8.1 context menu and put one string characters inside; I noticed though that dots `.` only appear if .txt's are **located in subfolders!** that's why I initially used `for /r`; have you got any clue? – Victor Novak Dec 10 '20 at 18:09
  • @aschipfl I also tried `echo/`, but didn't help. – Victor Novak Dec 10 '20 at 18:11
  • 1
    Use `echo(>>result.txt` instead of `echo.>> result.txt`. For the reason read completely the DosTips forum topic: [ECHO. FAILS to give text or blank line - Instead use ECHO/](https://www.dostips.com/forum/viewtopic.php?f=3&t=774) – Mofi Dec 10 '20 at 18:34
  • @Mofi **THANK YOU!!!** <3 – Victor Novak Dec 10 '20 at 18:36
  • 2
    PS: On FAT32 and exFAT drives the `for /R` loop does not produce the expected result as writing `result.txt` into the current directory while iterating over the list of `*.txt` files in current directory and its subdirectories directly from the file system results in processing the `*.txt` files in current directory more than once. The better __FOR__ loop is `for /F "delims=" %%i in ('dir *.txt /A-D /B /ON /S 2^>nul') do (` which works on all drives independent on file system as first the list of text files is loaded into memory and then iterating over the file names list in memory. – Mofi Dec 10 '20 at 18:41
  • 1
    PPS: The `dir` option `/ON` results in a different order of the file names than NTFS uses to store the file names in the file allocation table. So it is advisable that the file names are not `1.txt`, `2.txt`, ..., `9.txt`, `10.txt`, etc. but `01.txt`, `02.txt`, ..., `09.txt`, `10.txt`, etc. – Mofi Dec 10 '20 at 18:47
  • @Mofi could you please rewrite `for /F "delims=" %%i in ('dir *.txt /A-D /B /ON /S 2^>nul') do (` for, say "C:\Users\123\Desktop\Folder" - ?? – Victor Novak Dec 10 '20 at 18:49
  • 1
    @VictorNovak `for /F "delims=" %%i in ('dir "%UserProfile%\Desktop\Folder\*.txt" /A-D /B /ON /S 2^>nul') do (` for a recursive processing with file names with full path assigned to loop variable `i` or `for /F "eol=| delims=" %%i in ('dir "%UserProfile%\Desktop\Folder\*.txt" /A-D /B /ON 2^>nul') do (` for just file name with extension, but without file path assigned to loop variable `i`. The first solution requires to use `type "%%i">>result.txt` and the second solution `type "%UserProfile%\Desktop\Folder\%%i">>result.txt`. – Mofi Dec 10 '20 at 18:54
  • @Mofi thank you again so much! I didn't expect this task to consume all my day :D I'm currently reading this for details https://ss64.com/nt/dir.html – Victor Novak Dec 10 '20 at 18:59

2 Answers2

1

Thanks @Mofi, see his comments below the starting post!

This is a solution for а Folder on (any) user's Desktop:

for /f "delims=" %%i in ('dir "%UserProfile%\Desktop\Folder\*.txt" /a-d /b /on /s 2^>nul') do (
echo %%~fi>> result.txt
type "%%i">> result.txt
echo(>> result.txt
)
  • echo %%~fi>> result.txt adds full path to any *.txt file found in that folder (and subfolders);
  • type "%%i">> result.txt merges found *.txt files contents;
  • echo(>> result.txt is the new line character requested!

This code tested on NTFS and is promised to work on FAT\FAT32 etc. - unlike for /R (see @Mofi comments below the starting post!).

P.S.: you can launch this batch code from any location; also, use echo {anytext}>> result.txt after echo(>> result.txt to easily navigate between breaks in "result.txt" :)

P.P.S.: also, if you want to get rid of blank line in the EOF "result.txt" - use this:

set /a counter1=0
set /a counter2=0

::cycle 1
for /f "delims=" %%i in ('dir "%UserProfile%\Desktop\Folder\*.txt" /a-d /b /on /s 2^>nul') do (
set /a counter1+=1
)

::cycle 2
setlocal enableextensions enabledelayedexpansion
for /f "delims=" %%i in ('dir "%UserProfile%\Desktop\Folder\*.txt" /a-d /b /on /s 2^>nul') do (
echo %%~fi>> result.txt
type "%%i">> result.txt
set /a counter2+=1
if not !counter2!==%counter1% (echo(>> result.txt)
)
endlocal

Inspired by: https://stackoverflow.com/a/7522822/6859021

  • both cycles has the same for /f conditions;
  • ::cycle 1 counts number of files that are about to undergo the procedure;
  • ::cycle 2 is identical to original solution, except for "Inspired by" details;
  • ::* lines are comments: they don't affect code execution;
  • if not !counter2!==%counter1% (echo(>> result.txt) merely puts echo( for all lines, except for the last one! :D

Notice however that counters will work properly only if "result.txt" will NOT be located inside Folder of interest, or it's subfolders.

  • `%UserProfile%` doesn't work if user's `Desktop` is located on different HDD (when system drive is SSD, for example): `%HOMEPATH%\Desktop` does the charm for both! – Victor Novak Dec 11 '20 at 08:14
  • 1
    Neither `%UserProfile%\Desktop` nor `%HOMEPATH%\Desktop` are always correct to reference the directory being the user's desktop. See [How to create a directory in the user's desktop directory?](https://stackoverflow.com/a/58516212/3074564) It explains in full details how to query the user's desktop directory from Windows registry working even on user has changed the user's desktop directory for example to a directory being included for OneDrive synchronization. – Mofi Dec 11 '20 at 13:51
  • Batch syntax is so confusing, omg >< Thanks again @Mofi! – Victor Novak Dec 11 '20 at 15:06
0

First: I could not reproduce the problem where additional dots are added to the file.

However I found a different issue, that might have to do something with it. When you are iterating over all text-files, you get the result.txt at one point as well. (And other files you might add or change during runtime.)

So I created this basic script, which does exactly what you described as your desired behavior:

@echo off
:: clear 
rd testdir /s /q 2>nul

:: create files
md testdir
cd testdir
for /l %%i in (1 1 3) do (
  <nul set /p "=%%i">"%%i.txt"
)

:: combine the files
for /r %%f in (*.txt) do (
  if not "%%~nf"=="result" (
    type "%%f">>result.txt
    echo.>>result.txt
  )
)

:: show result
echo result.txt
type result.txt
pause
timlg07
  • 547
  • 6
  • 20