0

I have an input text file with some server names

I am trying to replace the 'new line' for each server with |.

abcdef.abcdef.abcdef
testing
example

When executed in cmd.exe my script doesn't parse all lines from the input file. Say, if I have 1000 servers in my input file, I can see the output in the Command Prompt window for just around 500 servers.

@echo off
setlocal enableextensions
SETLOCAL EnableDelayedExpansion
rem Purpose - To remove domain name of servers and convert line by line strings to | seperated strings.

type nul > Del_Output.txt

for /f "tokens=1 delims=." %%a in (Downtime.txt) do (

  echo(%%a>> Del_Output.txt
)
type Del_Output.txt

rem Initialize the output line
set "line="

rem Catenate all file lines in the same variable separated by "|"
for /F "delims=" %%a in (Del_Output.txt) do set "line=!line!|%%a"

rem Show final line, removing the leading "|"

rem echo !line:~1!>FinalOutput.txt
echo !line:~1!
rem type "C:\Users\AAithal\Desktop\MoogSoft_Downtime\FinalOutput.txt"
ENDLOCAL

Some pointers on the issue would be very helpful.

Compo
  • 36,585
  • 5
  • 27
  • 39
Abhinandan Aithal
  • 161
  • 2
  • 5
  • 12
  • Does Del_Output.txt have the same number of entries as Downtime.txt or FinalOutput.txt? Also, if you change the `|` to something else (like a semicolon) does it work correctly? – SomethingDark Jul 05 '19 at 15:47
  • 3
    Other than having a trailing pipe, would something like this single line [tag:batch-file] not work for you? `@(For /F UseBackDelims^=^ EOL^= %%A In ("Downtime.txt")Do @Set /P "=%%~nA|""FinalOutput.txt"` – Compo Jul 05 '19 at 15:52
  • @Compo Thanks for that code. It worked fine. I see a | added after the last entry too after updating your code. If i can get help on removing this last | that would be great. -Abhi – Abhinandan Aithal Jul 05 '19 at 16:24
  • @SomethingDark Yes, Downtime.txt has all entries, it is only the FinalOutput.txt which doesn't display all output. replacing | with , has same results / issue. – Abhinandan Aithal Jul 05 '19 at 16:26
  • Well, I'm confused. Not that *that*'s unusual - but showing your expected final output given the input would have made this much easier. – Magoo Jul 05 '19 at 17:03
  • @Magoo this is my expected Output - abcdef|testing|example -Abhi – Abhinandan Aithal Jul 05 '19 at 17:24
  • Does Del_Output have all entries? – SomethingDark Jul 05 '19 at 18:14
  • @AbhinandanAithal, you could remove the trailing pipe character by setting the output to a variable first, then send the variable, expanded to remove the last character, to your file. Also, just to let you know, some domains do not only have a single period character, so using your idea and my commented code, `domain.co.uk`, would end up as `domain.co`, not `domain`, if this is important to you, then you need to rethink the entire task. – Compo Jul 05 '19 at 18:16
  • @SomethingDark Yes, Del_Output has all entries. – Abhinandan Aithal Jul 05 '19 at 18:29
  • @AbhinandanAithal I suggest to replace second and third line in your batch file by `setlocal EnableExtensions EnableDelayedExpansion`. Read [this answer](https://stackoverflow.com/a/38676582/3074564) for details about the commands __SETLOCAL__ and __ENDLOCAL__ and what exactly happens on __every__ execution of `setlocal` without any parameter or with one or with two parameters. You use two times `setlocal`, but only once `endlocal`. One more `endlocal` missing in code is executed implicit by `cmd.exe` on exiting processing of this batch file. – Mofi Jul 05 '19 at 18:39
  • 3
    @AbhinandanAithal You have written that in the file are 1000 domains or server names. Do you know the [Command prompt (Cmd. exe) command-line string limitation](https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation) of 8192 characters (including terminating 0) which you exceed on concatenating so much strings with more than 7 characters with a vertical bar between? The code posted by Compo in his first comment worked around this limitation. – Mofi Jul 05 '19 at 18:48

2 Answers2

2

This should work:

@echo off
setlocal

set "first="
< nul (
for /F "delims=." %%a in (Downtime.txt) do (
   if not defined first (
      set "first=1"
      set /P "=%%a"
   ) else (
      set /P "=|%%a"
   )
)
echo/
) > Output.txt

As others have indicated already, the maximum length of a batch variable is 8192 characters, so all names that exceed such a size are not included in your code...

The solution is not use a variable to collect the output. The set /P command allows to output a string with no LF at end, so the input lines are just joined in a long output line.

Mofi
  • 46,139
  • 17
  • 80
  • 143
Aacini
  • 65,180
  • 12
  • 72
  • 108
1
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q56905805.txt"

SET "outline="
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
 FOR /f "tokens=1*delims=." %%i IN ("%%a") DO IF "%%j"=="" (
  SET "outline=!outline!|%%a"
 ) ELSE (
  IF DEFINED outline ECHO !outline!
  SET "outline=%%i"
 )
)
IF DEFINED outline ECHO !outline!
GOTO :EOF

You would need to change the setting of sourcedir to suit your circumstances. The listing uses a setting that suits my system.

I used a file named q56905805.txt containing your data for my testing.

The usebackq option is only required because I chose to add quotes around the source filename.

Assign each line to %%a, then reparse it with the delimiter. It it contains the delimiter, it's a new server, so output the previous one and start anew, else accumulate with the required separator.

Magoo
  • 77,302
  • 8
  • 62
  • 84